数组中内存的重新分配
Deallocation of memory in arrays
我已经完成了一个打开文件(读取二进制文件)的程序,并将所有单词(在文件中)保存在一个 char 数组中(根据单词的长度动态分配)。
这是代码:
char **leggi_stringhe(const char *filename, size_t *size) {
FILE *f = fopen(filename, "rb");
if (f == NULL) {
*size = 0;
return NULL;
}
int x;
if (fread(&x, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
char **stringhe = malloc((x) * sizeof(char));
for (int i = 0; i < x; i++) {
int z = 0;
if (fread(&z, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
stringhe[i] = malloc((z)* sizeof(char));
if (fread(stringhe[i], 1, z, f) != z) {
*size = 0;
return NULL;
}
stringhe[i][z] = 0;
}
*size = x;
fclose(f);
return stringhe;
}
int main(void) {
size_t t;
char **a = leggi_stringhe("file1.bin", &t);
for (int i = 0; i < t; i++)
free(a[i]);
free(a);;
}
该程序可以运行,但我在内存释放方面遇到问题。
leggi_stringhe函数调用后,变量a包含:
a[0] = "first"
a[1] = "second"
a[2] = "third"
但是当我试图像我写的那样释放整个 a 变量时,调试器停止并发出警告。
我受到这个问题的启发而编写了我的代码 Using Dynamic Memory allocation for arrays,但不明白为什么我在尝试解除分配时会收到此错误。
您对 malloc
的初始调用是错误的。您为 x
个字符 分配了 space,而不是指向 char
.
的指针
你在循环内的第二次调用是错误的,因为你没有为终止符分配 space。
最后,与您询问的问题无关,但如果循环内的 fread
调用失败,您将遇到内存泄漏。
您的代码存在一些问题:
这一行:
char **stringhe = malloc((x) * sizeof(char));
需要:
char **stringhe = malloc((x) * sizeof(char*)); /* or sizeof *stringhe */
因为你需要为stringhe
分配x
char*
个指针。
在您的第一个 for 循环中,您没有为 null-terminator 添加 +1
。它需要改为:
stringhe[i] = malloc(z+1); /* sizeof(char) = 1 */
您需要检查 return 个 malloc()
。不成功可以returnNULL
。您可以通过简单地检查 if (ptr == NULL)
来完成此操作,然后退出程序。允许失败的 malloc()
在程序中继续运行是不安全的。
for (int i = 0; i < t; i++)
正在比较 int
和 size_t
。这应该是 for (size_t i = 0; i < t; i++)
而不是。
我已经完成了一个打开文件(读取二进制文件)的程序,并将所有单词(在文件中)保存在一个 char 数组中(根据单词的长度动态分配)。
这是代码:
char **leggi_stringhe(const char *filename, size_t *size) {
FILE *f = fopen(filename, "rb");
if (f == NULL) {
*size = 0;
return NULL;
}
int x;
if (fread(&x, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
char **stringhe = malloc((x) * sizeof(char));
for (int i = 0; i < x; i++) {
int z = 0;
if (fread(&z, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
stringhe[i] = malloc((z)* sizeof(char));
if (fread(stringhe[i], 1, z, f) != z) {
*size = 0;
return NULL;
}
stringhe[i][z] = 0;
}
*size = x;
fclose(f);
return stringhe;
}
int main(void) {
size_t t;
char **a = leggi_stringhe("file1.bin", &t);
for (int i = 0; i < t; i++)
free(a[i]);
free(a);;
}
该程序可以运行,但我在内存释放方面遇到问题。 leggi_stringhe函数调用后,变量a包含:
a[0] = "first"
a[1] = "second"
a[2] = "third"
但是当我试图像我写的那样释放整个 a 变量时,调试器停止并发出警告。
我受到这个问题的启发而编写了我的代码 Using Dynamic Memory allocation for arrays,但不明白为什么我在尝试解除分配时会收到此错误。
您对 malloc
的初始调用是错误的。您为 x
个字符 分配了 space,而不是指向 char
.
你在循环内的第二次调用是错误的,因为你没有为终止符分配 space。
最后,与您询问的问题无关,但如果循环内的 fread
调用失败,您将遇到内存泄漏。
您的代码存在一些问题:
这一行:
char **stringhe = malloc((x) * sizeof(char));
需要:
char **stringhe = malloc((x) * sizeof(char*)); /* or sizeof *stringhe */
因为你需要为
stringhe
分配x
char*
个指针。在您的第一个 for 循环中,您没有为 null-terminator 添加
+1
。它需要改为:stringhe[i] = malloc(z+1); /* sizeof(char) = 1 */
您需要检查 return 个
malloc()
。不成功可以returnNULL
。您可以通过简单地检查if (ptr == NULL)
来完成此操作,然后退出程序。允许失败的malloc()
在程序中继续运行是不安全的。for (int i = 0; i < t; i++)
正在比较int
和size_t
。这应该是for (size_t i = 0; i < t; i++)
而不是。