为什么 2 个不同的字符串在 C 中具有相同的地址?

why 2 different strings have the same address in C?

下面的代码和示例 csv 文件。

我写的程序是csv reader。在 while 循环中,我将文件的行作为字符串获取,然后使用 sscanf 提取存储在局部变量中的数据。

我有 2 个字符串存储在 char* name 和 char* surname 中,但它们恰好具有相同的地址:

Printing description of name:
(char *) name = 0x000000010004da78 "Bob"
Printing description of surname:
(char *) surname = 0x000000010004da78 "Bob

我不明白为什么,因为它们有不同的变量名。

我希望得到那个问题的答案,但这不是我的问题:Temporary C strings have same address

我重命名了变量并重新构建了 .exe(使用 Xcode),但问题仍然存在。知道为什么会出现这个问题吗?

谢谢

代码

void readFileTest(FILE* *pFile, TTest* *pRootTest)
//Reads the content of the file, line by line
{
    int count=0;
    char string[MAX_SIZE];
    TTest *pTestCurrent=NULL, *pPrevious=NULL;

    //Reads first line (wich is the label line)
    fgets(string, MAX_SIZE, *pFile);
    printf("Column labelling : %s\n", string);

    //allocating pointer
    pTestCurrent=malloc(sizeof(TTest));
    pTestCurrent->ID=0;
    pTestCurrent->name="";
    pTestCurrent->surname="";
    pTestCurrent->mean=0.0;
    pTestCurrent->pNext=NULL;
    pTestCurrent->pPrevious=NULL;

    (*pRootTest)=pTestCurrent;
    pPrevious=pTestCurrent;

    //Extracts data of each line and stores it in a node
    while(fgets(string, MAX_SIZE, *pFile)) //reads line by line until the EOF
    {
         int identification=0;
         char* name;
         char* surname;
         float mean=0.0;

         //Counts iterations (lines) in the file
         count+=1;
         printf("Iteration n°%d\n", count);

         //Extracts data of the line in variables
         sscanf(string, "%d,%[^,],%[^,],%f", &identification, name, surname, &mean);

        //Assign data in variables to node in pTestCurrent
         pTestCurrent->ID=identification;
         pTestCurrent->name=name;
         pTestCurrent->surname=surname;
         pTestCurrent->mean=mean;

         //Displays data in node
         printf("Line content (stored in pTestCurrent) :\nID : %d\nNAME : %s\nSURNAME : %s\nMEAN : %f\n\n", pTestCurrent->ID, pTestCurrent->name, pTestCurrent->surname, pTestCurrent->mean);

         if(pTestCurrent==NULL)
         {
             printf("ERROR : pointer pTestCurrent is NULL, the programm will exit now\n");
             EXIT_FAILURE;
    }

         //Refresh pointer
         pTestCurrent->pNext=malloc(sizeof(TTest));
         pTestCurrent=pTestCurrent->pNext;
         pTestCurrent->pPrevious=pPrevious;
         pTestCurrent->pNext=NULL;
         pPrevious=pTestCurrent;
         }
};

示例文件:

ID,NAME,SURNAME,MEAN
1,Smith,Bob,4.32
2,Mason,Jack,9.21
3,Gabe,John,2.67

这里的问题是,在 while 循环中,您使用的是未初始化的指针。这些指针不能保证指向任何地方 有效 ,并且您正试图通过它们访问内存位置指针。这导致 undefined behavior

解决方案:在将它们作为参数传递给 sscanf() 之前,您需要确保它们指向一些可以被您的进程访问的有效内存。

你犯了两个错误:

  1. 当你sscanf

  2. 时你没有有效的记忆
  3. 您没有复制扫描的值。

第一个:

    sscanf(string, "%d,%[^,],%[^,],%f", &identification, name, surname, &mean);

这里namesurname只是指向char的指针,但它们并不指向你程序的内存(它们是未初始化的,可以指向任何地方。你很可能得到了一个分段故障)。相反,做:

    char name[64], surname[64];  // or any proper size for the names

您现在对您的 sscanf.

有了有效的记忆

其次,当您将扫描的数据复制到您的结构中时,您必须在您的结构中为数据分配内存。只有 pTestCurrent->name=name; 时,您将指向 name 指针 放在结构的名称字段中,但不复制数据。因此,在您的下一个 sscanf 中,您将直接覆盖数据。相反,做:

    pTestCurrent->name= malloc(strlen(name)+1);
    strcpy(pTestCurrent->name, name);