使用strncpy时为什么会出现分段错误?

Joe*_*Joe 0 c

我在使用strncpy和(指向结构) - >(成员)表示法时遇到分段错误:

我简化了我的代码.我初始化一个结构并将其所有标记设置为空字符串.然后声明一个指向结构的指针,并为其分配结构的地址.

我将指针传递给一个函数.我可以在函数的开头打印出结构的内容,但如果我尝试在strncpy函数中使用tp - > mnemonic,我会得到seg错误.谁能告诉我我做错了什么?

typedef struct tok  {
    char* label;
    char* mnem;
    char* operand;
}Tokens;

Tokens* tokenise(Tokens* tp, char* line)  {
    // This prints "load"
    printf("Print this - %s\n", tp -> mnem);

    // This function gives me segmentation fault
    strncpy(tp -> mnem, line, 4);

    return tp;
}

int main()  {
    char* line = "This is a line";
    Tokens tokens;
    tokens.label = "";
    tokens.mnem = "load";
    tokens.operand = "";

    Tokens* tp = &tokens;
    tp = tokenise(tp, line);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经使用printf语句来确认代码肯定在strncpy函数处停止执行.

Eri*_*ski 9

问题是tp-> mnem指向一个字符串文字,通常在只读的内存段中分配.因此覆盖它是违法的.很可能你需要做的是这样的事情:

Tokens tokens;
tokens.label = "";
tokens.mnem  = strdup("load");
tokens.operand = "";
Run Code Online (Sandbox Code Playgroud)

这将为您提供动态分配的内存块,然后您可以根据需要随意写入.当然,你还有其他一些问题:首先,你需要记住以后再释放那个记忆free; 第二,你必须知道你分配的缓冲区的大小,这样你就不会覆盖它.

如果您知道内容mnem永远不会超过4个字节,那么您可能会改变您的结构声明,如下所示:

typedef struct tok  {
    char* label;
    char mnem[5]; // note: +1 byte for a NULL terminator
    char* operand;
}Tokens;
Run Code Online (Sandbox Code Playgroud)

然后,你会像这样初始化它:

Tokens tokens;
tokens.label = "";
strcpy(tokens.mnem, "load");
tokens.operand = "";
Run Code Online (Sandbox Code Playgroud)

mnem虽然您仍有一些超出缓冲区的风险,但这可以减轻您管理内存的责任.


qrd*_*rdl 7

以下行

tokens.mnem = "load"
Run Code Online (Sandbox Code Playgroud)

分配mnem给字符串文字的地址,字符串文字通常位于只读数据段中,因此使用strncpy()或任何其他功能更改此内存将失败.