gpt4 book ai didi

c - 动态结构数组中的 malloc 动态数组

转载 作者:行者123 更新时间:2023-11-30 16:52:35 25 4
gpt4 key购买 nike

typedef struct {
char *word;
} STR;

int main()
{
STR *arr=(STR*)malloc(5*sizeof(*arr));
STR[2].word=(char*)malloc(200*sizeof(char));
STR[2].word=(char*)realloc(,400*sizeof(char));
return 0;
}

这不会工作并且会写出很多错误。如何在动态结构数组中动态分配数组?

最佳答案

您的主要问题是您正在使用 typedef姓名STR您应该在其中使用变量名称 arr分配和重新分配时arr[2].word .

不要转换 malloc 的返回值,这是没有必要的。请参阅:Do I cast the result of malloc?进行彻底的解释。您只需分配一个 5 STR 的数组即可是:

STR *arr = malloc (5 * sizeof (*arr));  /* allocate array of 5 STR */

(注意: sizeof 中的括号是可选的,因此也可以正确书写):

STR *arr = malloc (5 * sizeof *arr);    /* allocate array of 5 STR */

在您声明STR *arr = malloc (5 * sizeof (*arr))之后,您分配word如下:

arr[2].word = malloc (200 * sizeof *(arr[2].word));

不是

STR[2].word = malloc (200 * sizeof *(arr[2].word));

您必须验证每个分配。例如:

STR *arr = malloc (5 * sizeof (*arr));  /* allocate array of 5 STR */

if (!arr) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1; /* or handle error as appropriate */
}

从不realloc使用指针本身,如果 realloc失败,您丢失了指向原始数据的指针并且无法释放内存。相反,使用一个简单的临时变量:

void *tmp = realloc (arr[2].word, 400 * sizeof *(arr[2].word));
if (!tmp) {
fprintf (stderr, "error: realloc() virtual memory exhausted.\n");
return 1;
}
arr[2].word = tmp;

在您编写的动态分配内存的任何代码中,对于分配的任何内存块,您有 2 个责任:(1) 始终保留指向起始地址的指针内存块,因此,(2) 当不再需要它时可以释放。养成跟踪和释放分配的所有内存的习惯,而不是依靠退出来完成。当您开始编写在代码中的函数内分配内存的更复杂的代码时,这将带来好处。在这种情况下,您需要:

free (arr[2].word); /* free allocated memory */
free (arr);

将这些部分放在一起,您可以这样做:

typedef struct {
char *word;
} STR;

int main (void)
{
STR *arr = malloc (5 * sizeof (*arr)); /* allocate array of 5 STR */

if (!arr) { /* validate allocation */
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1; /* or handle error as appropriate */
}

/* allocate/validate arr[2].word */
if (!(arr[2].word = malloc (200 * sizeof *(arr[2].word)))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1; /* or handle error as appropriate */
}

/* realloc/validate using temporary variable */
void *tmp = realloc (arr[2].word, 400 * sizeof *(arr[2].word));
if (!tmp) {
fprintf (stderr, "error: realloc() virtual memory exhausted.\n");
return 1;
}
arr[2].word = tmp;

free (arr[2].word); /* free allocated memory */
free (arr);

return 0;
}

示例使用/Valgrind 输出

您必须使用内存错误检查程序来确保您没有在分配的内存块之外进行写入,尝试读取或基于未初始化的值进行跳转,并最终确认您已释放所有内存您分配的内存。

对于 Linux valgrind是正常的选择。有许多微妙的方法可以滥用指针或新内存块。使用内存错误检查器可以让您识别任何问题并验证您分配的内存的正确使用,而不是通过 segfault 发现问题存在。 。每个平台都有类似的内存检查器。它们使用起来都很简单,只需通过它运行您的程序即可。

例如,编译代码并将可执行文件保存为 ./bin/alloc ,然后您将基本使用 valgrind只需运行 valgrind将您的程序作为第一个参数:

$ valgrind ./bin/alloc
==8949== Memcheck, a memory error detector
==8949== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8949== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==8949== Command: ./bin/alloc
==8949==
==8949==
==8949== HEAP SUMMARY:
==8949== in use at exit: 0 bytes in 0 blocks
==8949== total heap usage: 3 allocs, 3 frees, 640 bytes allocated
==8949==
==8949== All heap blocks were freed -- no leaks are possible
==8949==
==8949== For counts of detected and suppressed errors, rerun with: -v
==8949== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认所有堆 block 均已释放 - 不可能发生泄漏并且同样重要错误摘要:0 个上下文中出现 0 个错误。 (注意:某些操作系统不提供足够的内存排除文件(排除系统和操作系统内存被报告为正在使用的文件),这将导致valgrind报告某些内存尚未被使用尽管您已经完成了工作并释放了您分配的和在您控制下的所有 block ,但仍被释放。)

仔细检查一下,如果有任何问题请告诉我。

(注意:C 喜欢小写名称,为常量和宏保留全部大写。这只是风格,所以这取决于您。)

关于c - 动态结构数组中的 malloc 动态数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41170830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com