You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeBlocks编译报错:头文件声明函数出现Undefined Reference

解决C++项目的Undefined Reference链接错误

问题1:匿名命名空间导致的链接错误

错误原因

匿名命名空间的成员仅在当前编译单元(.cpp文件)可见。implementation.hpp中在匿名命名空间声明deleteRepeats,当main.cpp包含该头文件时,会在main.cpp的匿名命名空间生成一个独立的函数声明;而implementation.cpp中定义的deleteRepeats属于它自己的匿名命名空间。这两个函数完全独立,链接器无法找到main.cpp中调用的函数定义,因此报错。

修复方案

去掉匿名命名空间,将函数声明为全局(或使用具名命名空间):

修改后implementation.hpp

#ifndef IMPLEMENTATION_HPP
#define IMPLEMENTATION_HPP

const int SIZE = 10;
char* deleteRepeats(char*);

#endif

implementation.cpp保持不变(全局函数定义)

#include "implementation.hpp"

char* deleteRepeats(char* array_to_edit)
{
    char new_array[SIZE];
    int num_of_unique_letters_seen = 0;
    for (int letter = 0; letter < SIZE; letter++)
    {
        bool already_exists = false;
        for (int letter_seen = 0; letter_seen < num_of_unique_letters_seen; letter_seen++)
        {
            if (array_to_edit[letter] == new_array[letter_seen])
            {
                already_exists = true;
            }
        }
        if (!already_exists)
        {
            new_array[num_of_unique_letters_seen] = array_to_edit[letter];
            num_of_unique_letters_seen++;
        }
    }
    // 注意:返回局部数组指针是错误行为,局部变量会在函数结束后销毁,指针变为野指针
    return &new_array[0];
}

main.cpp保持不变

#include <iostream>
#include "implementation.hpp"

int main()
{
    char originalArray[SIZE];
    originalArray[0] = 'a';
    originalArray[1] = 'b';
    originalArray[2] = 'b';
    originalArray[3] = 'c';
    originalArray[4] = 'a';
    originalArray[5] = 'c';
    originalArray[6] = 'a';
    originalArray[7] = 'c';
    originalArray[8] = 'b';
    originalArray[9] = 'c';
    char *noRepeats;
    noRepeats = deleteRepeats(&(originalArray[0]));
    std::cout << noRepeats;
    return 0;
}

问题2:具名命名空间dts的链接错误

错误原因

implementation.hpp中在dts命名空间声明了deleteRepeats,但implementation.cpp中定义的deleteRepeats是全局函数,不属于dts命名空间。链接器找不到dts::deleteRepeats的定义,因此报错。

修复方案

将函数定义放入dts命名空间,有两种写法:

方法1:用命名空间包裹函数定义

#include "implementation.hpp"

namespace dts {
char* deleteRepeats(char* array_to_edit)
{
    char new_array[SIZE];
    int num_of_unique_letters_seen = 0;
    for (int letter = 0; letter < SIZE; letter++)
    {
        bool already_exists = false;
        for (int letter_seen = 0; letter_seen < num_of_unique_letters_seen; letter_seen++)
        {
            if (array_to_edit[letter] == new_array[letter_seen])
            {
                already_exists = true;
            }
        }
        if (!already_exists)
        {
            new_array[num_of_unique_letters_seen] = array_to_edit[letter];
            num_of_unique_letters_seen++;
        }
    }
    for (int letter = 0; letter < SIZE; letter++)
    {
        array_to_edit[letter] = new_array[letter];
    }
    return array_to_edit;
}
} // 结束dts命名空间

方法2:用dts::限定函数名

#include "implementation.hpp"

char* dts::deleteRepeats(char* array_to_edit)
{
    char new_array[dts::SIZE];
    int num_of_unique_letters_seen = 0;
    for (int letter = 0; letter < dts::SIZE; letter++)
    {
        bool already_exists = false;
        for (int letter_seen = 0; letter_seen < num_of_unique_letters_seen; letter_seen++)
        {
            if (array_to_edit[letter] == new_array[letter_seen])
            {
                already_exists = true;
            }
        }
        if (!already_exists)
        {
            new_array[num_of_unique_letters_seen] = array_to_edit[letter];
            num_of_unique_letters_seen++;
        }
    }
    for (int letter = 0; letter < dts::SIZE; letter++)
    {
        array_to_edit[letter] = new_array[letter];
    }
    return array_to_edit;
}

额外注意事项

  • 第一个版本中返回局部数组new_array的指针是严重错误,局部变量会在函数结束后被栈销毁,返回的指针变为野指针,访问会导致未定义行为。建议改为动态分配内存(如new char[SIZE])或让调用者传入目标数组。
  • 第二个版本中,new_array的未初始化部分会被拷贝到输入数组,可能包含垃圾值。需要在new_array末尾添加字符串结束符'\0',否则std::cout输出时会越界读取。

内容的提问来源于stack exchange,提问作者Frasher Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:43:17