将字符串数组作为参数传递并在 C 函数中动态修改它

Passing an array of strings as argument and modifying it dynamically within the function in C

我需要在 C 中动态填充字符串数组。这是我的代码示例。编译良好,分段错误。是否可以实现此功能?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_FILE_NAME_LENGTH 255

void loadList(char*** files,int *filesSize);

int main (int argc, char *argv[])
{
  char** files;
  int filesSize=-1;

  loadList(&files, &filesSize);
  //printf("filesize= %d\n",filesSize );
  for(int i=0;i< filesSize;i++) printf("%s\n", files[i]);
  free(files);

  return 0;
}

////////////////////////////////////////////////////////////////////////////////

void loadList(char*** files,int *filesSize){
 *filesSize=3;
 //some arry for the example
 char *values[] = {"100.dat", "150.dat", "200.dat"};
 for(int i=0;i< *filesSize;i++){
   *files=(char**) realloc(*files,(i+1) * sizeof(**files));
   *files[i]=malloc((MAX_FILE_NAME_LENGTH+1) * sizeof(char*));
   strcpy(*files[i],values[i]);
   printf("%s\n", files[i]);
 }
}


*files = (char **)realloc(*files, (i + 1) * sizeof(**files)); 中,您依赖 *files 指向已分配的内存 NULL。两者都不是真的。

*files[i] 也应该是 (*files)[i] 因为 operator precedence.

您还忘记了 free 在循环内进行的分配。修复可能如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_FILE_NAME_LENGTH 255

void loadList(char ***files, size_t *filesSize) {
    // some array for the example
    const char *values[] = {"100.dat", "150.dat", "200.dat"};
    *filesSize = sizeof values / sizeof *values;

    *files = NULL; // crucial for first realloc

    for (int i = 0; i < *filesSize; i++) {
        *files = realloc(*files, (i+1) * sizeof **files);
        // I'm using strlen here instead of MAX_FILE_NAME_LENGTH but
        // you can change that back if you want more space than the
        // strings really need.
        (*files)[i] = malloc((strlen(values[i]) + 1) * sizeof(char));
        strcpy((*files)[i], values[i]);
    }
}

int main(int argc, char *argv[]) {
    char **files;
    size_t filesSize = -1;

    loadList(&files, &filesSize);
    // printf("filesize= %d\n",filesSize );
    for (int i = 0; i < filesSize; i++) printf("%s\n", files[i]);

    // free what was allocated in the loop
    for (int i = 0; i < filesSize; i++) free(files[i]);
    free(files);

    return 0;
}

关于 files = realloc(*files, ... 的一个注释: 如果 realloc 失败,您将丢失原始指针并且将无法恢复。要么将 return 值分配给临时变量并检查它是否有效,要么从函数中 return(将 *filesSize 设置为 i 后) 如果 *files == NULL.

退出程序

规则是每个 xalloc 调用必须存在一个 free。并且使用 return 值可以避免额外的间接级别。

如果您只想为每个字符串分配使用的大小,第一种方法是 return 指针数组:

char** loadList(int* filesSize);

int main(int argc, char* argv[])
{
    char** files;
    int filesSize = -1;

    files = loadList(&filesSize);
    //printf("filesize= %d\n",filesSize );
    for (int i = 0; i < filesSize; i++) printf("%s\n", files[i]);
    for (int i = 0; i < filesSize; i++) free(files[i]);
    free(files);

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

char ** loadList(int* filesSize) {
    //some arry for the example
    char* values[] = { "100.dat", "150.dat", "200.dat" };
    *filesSize = sizeof(values) / sizeof(values[0]);
    char** files = malloc(*filesSize * sizeof(*files));
    for (int i = 0; i < *filesSize; i++) {
        files[i] = strdup(values[i]);
        printf("%s\n", files[i]);
    }
    return files;
}

或者,如果您希望所有文件名都具有最大大小,则最好构建一个二维数组,使其具有一个 allocation/deallocation 步骤:

#define MAX_FILE_NAME_LENGTH 255

typedef char FileName[MAX_FILE_NAME_LENGTH];

FileName* loadList(int* filesSize);

int main(int argc, char* argv[])
{
    int filesSize = -1;

    FileName *files = loadList(&filesSize);
    //printf("filesize= %d\n",filesSize );
    for (int i = 0; i < filesSize; i++) printf("%s\n", files[i]);
    free(files);

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

FileName* loadList(int* filesSize) {
//some arry for the example
    char* values[] = { "100.dat", "150.dat", "200.dat" };
    *filesSize = sizeof(values) / sizeof(values[0]);
    FileName *files = malloc(*filesSize * sizeof(*files));
    for (int i = 0; i < *filesSize; i++) {
        strcpy(files[i],values[i]);
        printf("%s\n", files[i]);
    }
    return files;
}