【问题标题】:memset throwing segmentation faultmemset 抛出分段错误
【发布时间】:2012-11-26 00:10:41
【问题描述】:

我在编写一个从文件中提取字符串作为更大程序的一部分的函数时遇到了一些问题。一切似乎都运行良好,除非我使用 memset 或 bzero 擦除我一直在使用的字符数组。我已经解决这个问题一个多小时了,无论我做什么,我都会遇到段错误。我在 bzero 和 memset 上都收到了这个错误。请帮帮我。 我在下面附上我的代码。打印了“Come out of addfront”语句,但没有打印“Done with all bzero”语句。那时我遇到了分段错误。谢谢

void extractFileData(FILE *fp , char clientName[])
{
    char tempFileName[50], tempFilePath[100], tempFileSize[50];
    struct stat fileDetails;

    while(fgets(tempFileName, sizeof(tempFileName), fp)!= NULL)
    {
        if((newLinePos = strchr(tempFileName, '\n')) != NULL)
        {
            *newLinePos = '\0';
        }

        strcat(tempFilePath, "SharedFiles/");
        strcat(tempFilePath, tempFileName);

        if(stat(tempFilePath, &fileDetails) < 0)
        {
            perror("Stat error");
            exit(1);
        }

        //Copy it into a string
        sprintf(tempFileSize, "%zu", fileDetails.st_size);
        printf("temp file size: %s\n", tempFileSize);

        //Add all these details to the file list by creating a new node
        addFront(tempFileName, tempFileSize, clientName);

        printf("Come out of addfront\n");

        memset(&tempFileName, 0, 45);
        printf("Done with all bzero\n");
        memset(&tempFileSize, 0, sizeof(tempFileSize));
        memset(&tempFilePath, 0, sizeof(tempFilePath));

        printf("Done with all bzero\n");
    }
}   

编辑:

void addFront(char fileName[], char fileSize[], char clientName[])
{
    FILENODE* n;
    printf("Inside add front function\n");
    strcpy(n->fileName, fileName);
    printf("n->filename: %s\n", n->fileName);
    strcpy(n->fileSize, fileSize);
    printf("n->filesize: %s\n", n->fileSize);
    strcpy(n->ownerName, clientName);
    printf("n->ownername: %s\n", n->ownerName);
    myFileList.head = n;
    printf("Did it go past myfilelist head = n\n");
    myFileList.numOfNodes++;
    printf("num of nodes: %d\n", myFileList.numOfNodes);
}

我已经为 addFront 函数添加了我的代码。它基本上增加了 struct myFileList 的详细信息,它基本上是一个实现 的一个链表。 FILENODE 代表列表中的每个条目。

编辑:

添加我正在使用的结构

 struct fileNode
 {
      char fileName[50];
      char fileSize[50];
          char ownerName[25];
      struct fileNode* next;
 };

 struct fileList
 {
      struct fileNode* head;
      struct fileNode* tail;
       int numOfNodes;
 };

 typedef struct fileList FILELIST;
 typedef struct fileNode FILENODE;

【问题讨论】:

  • addFront 是做什么的?顺便说一句:当你做strcat(tempFilePath, "SharedFiles/"); tempFilePath 时没有初始化。在某处可能是也可能不是 \0。
  • 顺便说一句:你应该尽可能避免使用 strcat 。我的建议是将两个 strcat() 调用合并为一个 ret = snprintf(tempFilePath, sizeof tempFilePath,"%s/%s", "SharedFiles", tempFileName); 调用。
  • 您的strcat 确实很糟糕。但是没有语言级别的原因您的代码会在那些memsets 上崩溃。如果确实如此,我看到的唯一可能性是addFront 以某种方式破坏了程序堆栈结构,仍然允许它成功返回您的函数,但导致它在第一个memset 时崩溃。
  • 未初始化的 tempFilePath + 随后的 strcat() 怎么样?甚至在调用神秘的 addFront() 之前,损坏可能已经造成。
  • 感谢您的所有 cmets/输入。 tempFilePath 似乎工作正常,因为我在将其传递给 stat() 调用之前将其打印出来进行了测试。由于stat() 调用工作正常,我猜tempFilePath,至少在这一点上,似乎没问题。但我会确保我更改它以避免大家提到的关于在未初始化的变量上使用strcat 的问题。

标签: c segmentation-fault memset


【解决方案1】:

我不知道你的程序为什么会在那里崩溃。但我可以在程序中出现另一个错误。先修复另一个错误,看看是否还有问题。

这是错误

strcat(tempFilePath, "SharedFiles/");
strcat(tempFilePath, tempFileName);

tempFilePath 变量未初始化。这可能巧合不会崩溃,但你不能指望它不会崩溃。它可能会在您的堆栈上乱涂乱画。

改为这样做:

snprintf(tempFilePath, sizeof(tempFilePath), "SharedFiles/%s", tempFileName);

最后,无需将数组归零。数组的内容不会在下一次循环迭代中使用,所以你不妨忽略它们。

void extractFileData(FILE *fp , char clientName[])
{
    char tempFileName[50], tempFilePath[100], *newLinePos;
    struct stat fileDetails;
    while (fgets(tempFileName, sizeof(tempFileName), fp)) {
        if ((newLinePos = strchr(tempFileName, '\n')))
            *newLinePos = '\0';
        snprintf(tempFilePath, sizeof(tempFilePath),
                 "SharedFiles/%s", tempFileName);
        if (stat(tempFilePath, &fileDetails) < 0) {
            perror("Stat error");
            exit(1);
        }
        printf("temp file size: %zu\n", tempFileSize);
        addFront(tempFileName, tempFileSize, clientName);
    }
}   

snprintf() 函数确实是在 C 中进行此类工作的第一选择。使用 snprintf() 编写“显然不会崩溃”的代码很容易,而不是“显然不会崩溃”的代码崩溃”。

如果您的代码仍然崩溃,则说明其他地方存在错误。

【讨论】:

  • 我会实施并回复您。
  • 您可能需要检查 snprintf() 的返回值。这并不重要,但可能会有所帮助。
  • 我将代码更改为使用snprintf 而不是strcat,就像您建议的那样。我仍然有相同的分段错误。 @wildplasser 也这样做了。没关系
  • @因为我用 snprintf 替换了 strcat,就像 Dietric Epp 所说的那样,我实际上不需要将数组归零,因为这些值会被覆盖。所以现在我已经通过删除 memset 语句解决了这个问题,一切都按预期工作。但我仍然不明白为什么 memset 在那时给我一个 seg 错误。
  • 好吧,实际上我的 snprintf() 建议是第一位的。 WRT memset():这是未定义行为的秘密,任何事情都可能发生。任何时候。这就像西班牙宗教裁判所!
【解决方案2】:

addFront() 需要 n = malloc( sizeof *n) 才能对它进行任何操作。

【讨论】:

  • 另外:结构内的指针也需要设置为可用值。 (我什至不知道它是否是指针,它是一个非常秘密的结构,不知何故)
  • @wildplasser:很好,分配使用的是堆栈上的地址,一旦函数返回,这些地址就无用了。
  • @wildplasser 我使用的结构没有什么秘密。我只是不想添加可能对解决问题没有用的额外信息。
  • 所以,它是结构内的数组。 (但不涉及结构,只有一个未初始化的指向不存在结构的指针)
  • @tomlogic 我现在正在使用n = malloc(sizeof *n),现在一切正常。谢谢
猜你喜欢
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多