malloc动态数组中的动态数组结构
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;
}
这不起作用,写了很多错误。 如何动态地在动态数组结构中分配数组?malloc动态数组中的动态数组结构
这似乎是多余的。但是,如果您尝试使用您的结构创建一个字符串数组,其中第三个元素以malloc作为199个字符的字符串,然后作为399个字符的字符串实现,您可以这样做:
STR *arr = (STR*)malloc(5*sizeof(STR));
arr[2].word = (char*)malloc(200*sizeof(char));
arr[2].word = (char*)realloc(arr[2].word,400*sizeof(char));
这可以纠正错误,但不是很好的C代码。 a)不输出'malloc'的结果,b)使用指针变量的引用,而不是它的类型,例如'STR * arr = malloc(5 * sizeof * arr);',c)'sizeof char)'被定义为'1',因此告诉编译器解决代码混乱的问题; d)理想情况下'realloc'的返回值应该存储在临时变量中,所以如果调用失败,你仍然可以做一些事情与原始数据。 –
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char *word;
}STR;
int main(){
STR *arr=(STR*)malloc(5*sizeof(STR));
arr[2].word=(char*)malloc(200*sizeof(char));
if(realloc(arr[2].word, 400*sizeof(char))==NULL){
/* increasing char array size from 200 to 400 failed. 200 char array was unchanged */
printf("increasing array size not OK\n");
}
else{
printf("increasing array size OK\n");
}
free(arr[2].word);
free(arr);
return 0;
}
'printf(“增加数组大小OK \ n”);'不,它不好。 –
...因为你失去了新的指针。 –
您的主要问题是你正在使用的typedef
名STR
你应该分配和再分配arr[2].word
时,可以使用变量名arr
。
做不是投下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)
务必确认所有堆块被释放 - 没有泄漏是可能的和同样重要的错误摘要:0错误从0上下文。 (注意:某些操作系统不提供足够的内存排除文件(排除系统和操作系统内存被报告为正在使用),这将导致valgrind
报告某些内存尚未释放,尽管您已完成你的工作,并释放所有块,你分配,并在你的控制下。)
看看它,让我知道你是否有任何问题。
(注:C有利于小写的名称,保留全部大写的常量和宏这只是风格,所以它是由你)
'STR [2]'应该是'ARR [2 ]',但只有在您确认第一个'malloc'调用成功后。另外,在'malloc'调用上丢失 - 它们是不必要的,根据C89标准可以掩盖一个错误。 –
你错过了'realloc'的第一个参数。 –