c - char ** 对象是如何保存的?

标签 c arrays string file memory

<分区>

今天问我,char ** 对象是如何保存在内存或二进制文件中的。我使用以下代码片段对其进行了测试:

char **array  = (char *)malloc(3 * sizeof(char *));

array[0] = "Foo";         // Length: 3
array[1] = "Long string"; // Length: 11
array[2] = "Bar";         // Length: 3   => Full length: 17

int length = 17;

我将这个数组写入文件:

FILE *file = fopen(...);
fwrite(array, length, 1, file);
fclose(file);

很棒的是,当我用下面的代码从文件中再次读取这个数组时,字符串长度被成功读取而没有保存超过 17 个字节。

FILE *file   = fopen(...);
int   length = 17;

char **array = (char *)malloc(length);

int index        = 0;
int parsedLength = 0;
while (parsedLength < length)
{
    char *string       = array[index];
    int   stringLength = strlen(string);

    printf("%i: \"%s\" (%i)\n", index, string, stringLength);

    parsedLength += stringLength;
    ++index;
}

我得到的输出等于:

0: "Foo" (3)
1: "Long string" (11)
2: "Bar" (3)

编译器如何知道数组中的每个字符串有多长?

最佳答案

指针被保存到像数字(或更好的地址)这样的文件中,因此您的代码可以工作的事实是您可能在同一个运行中将它们保存并加载到同一个程序中这一事实造成的错觉(因此,由于这些string 是字面量,它们的地址大多固定在数据段中)。

你所做的是完全错误的,因为数组在内存中的布局如下(我假设 4 字节指针):

XXXXXXXX YYYYYYYY ZZZZZZZZ ( = 12 bytes)
   ^        ^        ^
   |        |       pointer to "Bar"
   |      pointer to "Long String"
 pointer to "Foo"

但是您在文件中保存了 17 个字节,其中 12 个只是内存地址。

要在文件中正确保存字符串,您当然需要存储包含的全部数据及其长度。像这样的东西:

for (int i = 0; i < ARRAY_LENGTH; ++i) {
  char *string = array[i];
  unsigned int length = strlen(string);
  fwrite(&length, sizeof(unsigned int), 1, out);
  fwrite(string, sizeof(char), length, out);
}

for (int i = 0; i < ARRAY_LENGTH; ++i {
  unsigned int length;
  fread(&length, sizeof(unsigned int), 1, in);
  array[i] = calloc(sizeof(char), length);
  fread(array[i], sizeof(char), length, in);
}

关于c - char ** 对象是如何保存的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16551430/

相关文章:

c - Visual Studio Code 不包含 C 头文件

c - 有人知道nvidia产品(Kepler)中warp报废的机制吗?

java - 将单个二进制字符串值拆分为数组

C++ 2 字节数组计算(字符数组、字符串和整数)

具有指定辅音比例的 C# 随机字母生成器 :vowels

c++ - 无法找到/打开输入级联

c - sparc64 上 sparc 汇编代码的 unsigned long long int 问题

c++ - 可变长度数组在主函数中编译,但在类声明中不编译?

php - Php Pdo 中的变量未定义

从 C 文件更改头文件中结构变量中的 char 数组会弄乱数组