【问题标题】:Failing to assign memory to a pointer of a pointer未能将内存分配给指针的指针
【发布时间】:2021-04-13 00:56:12
【问题描述】:

我的问题是它无法将内存分配给 (char*) 指针,我似乎无法理解为什么。 我回顾了其他类似的问题,但我似乎无法掌握答案。 我试图返回一个字符串列表,但我知道在 C 中我不能返回 char**,但我可以通过 char** 参数来做到这一点。我的尝试是在下面的代码 sn-ps 中。

在交流中

void list(char** fileList) {
    int fileIndex = 0;
    fileList = (char**)malloc(DIRECTORY_SIZE * sizeof(char*));
    while ((dir = readdir(currentDirectory)) != NULL)
    {
       fileList[fileIndex] = (char*)malloc(FILENAME_LENGTH * sizeof(char)); //It fails here
       fileList[fileIndex] = strncpy(fileList[fileIndex], dir->d_name, FILENAME_LENGTH);
       fileIndex++;
       printf("%s\n", fileList[fileIndex]);
    }
}

在 main.c 中

int main() {
    char** fileList;
    list(fileList);
    for(int i = 0; i < 10; i++) {
        printf("%s\n", fileList[i]);
    }
}

我已经看过这些问题了:

【问题讨论】:

  • 该函数处理参数表达式值的副本。更改副本不会影响原始参数。所以在 main 你有未初始化的指针 char** fileList;调用函数后仍然保持原样。
  • "...但我知道在 C 中我不能返回 char**" 谁告诉你的?您可以返回 char** 值 - 就您而言,这样做是有意义的。
  • @VladfromMoscow,是的,这是有道理的,但我仍然无法在函数内部分配内存。
  • 如果将while 条件测试更改为while (fileIndex &lt; DIRECTORY_SIZE &amp;&amp; (dir = readdir(currentDirectory)) != NULL) 会怎样?
  • fileIndex++;printf("%s\n", fileList[fileIndex]); 语句在while 循环中是错误的,因此它试图打印一个由垃圾指针值定位的字符串。此外,如果任何dir-&gt;d_name 字符串至少与FILENAME_LENGTH 一样长,strncpy(fileList[fileIndex], dir-&gt;d_name, FILENAME_LENGTH); 将不会附加空终止符。

标签: c pointers memory-management


【解决方案1】:

发生的情况是内存指针fileList被复制到列表函数,当列表函数更改指针时,初始指针不会改变。

要解决这个问题,你可以给它一个指向指针的指针来改变实际的指针值,像这样:

void list(char*** fileList) {
    int fileIndex = 0;
    *fileList = (char**)malloc(DIRECTORY_SIZE * sizeof(char*));
    while ((dir = readdir(currentDirectory)) != NULL)
    {
       *fileList[fileIndex] = (char*)malloc(FILENAME_LENGTH * sizeof(char)); //It fails here
       *fileList[fileIndex] = strncpy(fileList[fileIndex], dir->d_name, FILENAME_LENGTH);
       fileIndex++;
       printf("%s\n", fileList[fileIndex]);
    }
}

int main() {
    char** fileList;
    list(&fileList);
    for(int i = 0; i < 10; i++) {
        printf("%s\n", fileList[i]);
    }
}

但我个人觉得这有点笨拙,所以最好这样做:

char** list(void) {
    char** fileList;
    int fileIndex = 0;
    fileList = (char**)malloc(DIRECTORY_SIZE * sizeof(char*));
    while ((dir = readdir(currentDirectory)) != NULL)
    {
       fileList[fileIndex] = (char*)malloc(FILENAME_LENGTH * sizeof(char)); //It fails here
       fileList[fileIndex] = strncpy(fileList[fileIndex], dir->d_name, FILENAME_LENGTH);
       fileIndex++;
       printf("%s\n", fileList[fileIndex]);
    }
    return filelist;
}

int main() {
    char** fileList = list();
    for(int i = 0; i < 10; i++) {
        printf("%s\n", fileList[i]);
    }
}

【讨论】:

  • char** list() 应该是 char** list( void )char** list() 是一个接受不确定数量参数的函数。 char** list( void ) 是一个不带参数的函数。它们不是一回事。
  • 我不知道。我不经常使用 C,主要是 C++,我不认为那是一回事。
  • 这不是 - 在 C++ 中 char** list()char** list( void ) 相同。它与原型在 C++ 中是强制性的和(最初)在 C 中是可选的有关。
  • 是的,这很有道理。
猜你喜欢
  • 2018-05-16
  • 2013-12-10
  • 2011-01-16
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
相关资源
最近更新 更多