【问题标题】:Segmentation fault when doing strcpy执行 strcpy 时出现分段错误
【发布时间】:2017-05-30 04:20:08
【问题描述】:

我已经开始学习 C 并且一直在做一些小程序来学习。现在我正在处理内存指针,我有一个简短的问题。

据我了解,我在下面编写的程序导航到 /proc/sys/net/ipv4/conf/ 目录并打印出那里列出的目录。我的意图是在函数 getSysctlNames() 中分配内存,然后在调用者 main() 中释放它。 getSysctlNames() 还应该返回它找到的目录名称的数量。我读过这不是最好的主意(在函数中分配并从调用者处释放),但我只是想鬼混并学习而不是遵循模式。我的问题是我在运行 strcpy 函数时在第 55 行获得了分段错误。我不确定我做错了什么。任何帮助将不胜感激!

int getSysctlNames(char** namesPointer);

int main(int argc, char **argv) {
    char** namesPointer;
    int numberOfNames = getSysctlNames(namesPointer);
    printf("Number of files: %i\n", numberOfNames);
    int i = 0;
    for (i = 0; i <= numberOfNames; i++) {
        printf("%s\n", namesPointer[i]);
        free(namesPointer[i]);

    }
    free(namesPointer);
    return 0;
}

int getSysctlNames(char** namesPointer) {
    int numberOfNames = 0;
    DIR *directory = opendir("/proc/sys/net/ipv4/conf/");
    if (directory) {
        struct dirent *directoryEntry;
        while ((directoryEntry = readdir(directory)) != NULL) {
            if (strcmp(directoryEntry->d_name, ".") != 0 &&
                strcmp(directoryEntry->d_name, "..") != 0) {
                numberOfNames++;
            }
        }
        closedir(directory);
    } else {
        return -1;
    }
    if (numberOfNames == 0) return 0;
    namesPointer = (char**) malloc(numberOfNames * sizeof(char*));
    if (namesPointer == NULL) {
        return -1;
    }
    directory = opendir("/proc/sys/net/ipv4/conf/");
    if (directory) {
        struct dirent *directoryEntry;
        int i = 0;
        while ((directoryEntry = readdir(directory)) != NULL) {
            if (strcmp(directoryEntry->d_name, ".") != 0 &&
                strcmp(directoryEntry->d_name, "..") != 0) {
                namesPointer[i] = malloc((strlen(directoryEntry->d_name) + 1) * sizeof(char));
                if (namesPointer[i] = NULL) {
                    int j = i - 1;
                    while (j >= 0) {
                        free(namesPointer[j]);
                        j--;
                    }
                    free(namesPointer);
                    return 0;
                }
                printf("%s\n", directoryEntry->d_name);
                strcpy(namesPointer[i], directoryEntry->d_name);
                printf("Got to 2\n");
                i++;
            }
        }
        closedir(directory);
        return numberOfNames;
    }
    free(namesPointer);
    return -1;
}

【问题讨论】:

  • 我到了int numberOfNames = getSysctlNames(namesPointer); .. 这行是错误的,因为您将未初始化的变量传递给函数(这会导致未定义的行为)。也许你错过了 C 使用 pass-by-value - 一个函数接收其参数的副本。考虑到这一点,检查你的其余代码,你显然需要重新设计你的函数调用
  • if (namesPointer[i] = NULL) 也是个问题;如果您使用现代编译器并启用警告,那么编译器会为您指出这两个问题
  • 即使使用最糟糕的编译器,strcpy(&amp;namesPointer[i], 也应该会给出一条消息,告诉您存在问题。我猜你要么根本不阅读编译器输出,要么忽略它
  • if (namesPointer[i] = NULL) 是问题所在。在函数中传递一个未初始化的变量不是,而是一个可能导致问题的草率编程。
  • 如果您打算在 main 中使用 namePointer 并且您没有从函数返回指向它的指针,那么您需要 char* namesPointer; 并且调用是 int numberOfNames = getSysctlNames(&amp;namesPointer);(否则函数只是对 pointer-to-pointer-to-type 的副本进行操作。)您还可以使用相同的调用保留指向 type 的指针的指针,但是您的声明将要求您成为3 星 程序员(不是补充)

标签: c malloc strcpy


【解决方案1】:

你分配内存,然后用 NULL 覆盖指针值:

namesPointer[i] = malloc((strlen(directoryEntry->d_name) + 1) * sizeof(char));
if (namesPointer[i] = NULL) {...

应该是

if (namesPointer[i] == NULL)

if (!namesPointer[i])

【讨论】:

  • 谢谢。疲劳的眼睛似乎是这里的原因,我错过了额外的等号
  • 有些人会写if (NULL == ptr) 依赖编译器来选择这种错误,但我不喜欢这样。在我看来很难看。此外,现代编译器会警告这类问题。
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 2018-03-17
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多