简体   繁体   English

意外的strcpy段错误

[英]An unexpected strcpy segfault

I've discovered a segfault that I'm having trouble parsing. 我发现一个segfault无法解析。 Lest you think I haven't searched, I don't think the issue is the same as in this question . 免得您认为我没有搜索过,我认为问题与该问题相同。 I have the following typedef'd structure: 我有以下类型定义的结构:

typedef struct usage usage;
struct usage{
      char name[9]; 
      int loc;  
      usage *next;
};

I'm reading data from a file that consists of a number K followed by K pairs (S,D) where S= an 8-character string [this is a variable name] and d= an integer [a memory location]. 我正在从一个文件中读取数据,该文件由数字K和其后的K对(S,D)组成,其中S = 8个字符的字符串[这是变量名]和d =整数[存储位置]。

Here's the code that's causing the error: 这是导致错误的代码:

void addUse(int index,char *nm, int addr){
     usage *temp;
     strcpy(temp->name,nm); //segfault here. 
     temp->loc = addr;
     temp->next= NULL;
    /* more processing */
}

To make this clearer, I am calling this function from a block where I have 为了使这一点更清楚,我从一个我有

int dummyIndex = 1;
char s1[9];
int val1; 
scanf(" %s %d, s1, &val1);
addUse(dummyIndex, s1, val1);

It seems like in the question I linked to the issue is that they do not allocation the char on the heap. 似乎在我链接到该问题的问题中,它们没有在堆上分配char I am not sure what's happening here. 我不确定这里发生了什么。 Using identical calls to strcpy on another struct with a field char name[9] works just fine. 在具有字段char name[9]另一个struct上对strcpy使用相同的调用就可以了。

What am I missing? 我想念什么? What have I over looked? 我看了什么?

Thanks in advance! 提前致谢!

You've forgotten to initialize the temp pointer, so it's pointing to random memory. 您忘记了初始化临时指针,因此它指向的是随机内存。 When you then write 当你写的时候

strcpy(temp->name, mm);

You're following a pointer to a random address and writing bytes there, hence the segfault. 您正在跟踪一个指向随机地址的指针,并在其中写入字节,因此出现了段错误。

The problem is in the following line of your code 问题出在代码的以下行中

usage *temp;
strcpy(temp->name,nm); //segfault here. 

You are not initializing the temp pointer so it is taking a garbage value. 您没有初始化temp指针,因此它正在获取垃圾值。

Try initializing it before strcpy 尝试在strcpy之前对其进行初始化

usage *temp = malloc(sizeof(usage));

Hope this helps. 希望这可以帮助。

Here's my issue: 这是我的问题:

in other calls I make sure to set temp = malloc(sizeof(struct)); 在其他调用中,我确保设置temp = malloc(sizeof(struct)); not in this one so I'm trying to write to memory that hasn't been allocated!. 不在这其中,所以我试图写入尚未分配的内存!

The problem with your code is clear, and the SegFault happens in the exact location where it should. 代码的问题很明显,并且SegFault发生在应有的确切位置。 The reason is that you are using memory you haven't previously allocated. 原因是您正在使用以前未分配的内存。

void addUse(int index,char *nm, int addr){
     usage *temp;
     strcpy(temp->name,nm); //segfault here. 
     // ...
}

When you declare " usage *temp;" 当您声明“ 用法 * temp;”时 you're creating a pointer temp of type usage . 您正在创建使用类型的指针温度 Terrific. 了不起。 But... where is the pointer pointing to? 但是...指针指向哪里? You don't know. 你不知道 The value of temp , the memory address it contains is the garbage that happens to be in the place it occupies in memory when it is created (other programming languages give a default value to uninitialized variables, but C is not in that group). temp的值(它包含的内存地址)是创建时恰好位于其在内存中的位置的垃圾(其他编程语言为未初始化的变量提供默认值,但C不在该组中)。

So... you're being lucky. 所以...你很幸运。 Your program is best described as " undefined behaviour ", since it is possible that temp contains a memory address that casually is unoccupied: your program could run pass this function, crash elsewhere, and you would not have a clue about why. 最好将您的程序描述为“ 未定义的行为 ”,因为temp可能包含一个随意占用的内存地址:您的程序可以通过该函数运行,在其他地方崩溃,并且您不知道原因。

Another problem is that you should return the new struct usage, while your function is returning void . 另一个问题是,当函数返回void ,您应该返回新的结构用法。

This is the function as it should be: 这是应该的功能:

usage * addUse(int index,char *nm, int addr){
     usage *temp = malloc(sizeof(usage));

     if ( temp == NULL) {
         fprintf(stderr, "Not enough memory");
         exit(EXIT_FAILURE);
     }

     strcpy(temp->name,nm); //segfault here. 
     temp->loc = addr;
     temp->next= NULL;
    /* more processing */

     return temp;
}

I understand that you should link the pointer returned by addUse() to a linked list. 我知道您应该将addUse()返回的指针链接到链接列表。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM