C 内存分配-按引用字符串数组参数调用

C 内存分配-按引用字符串数组参数调用,c,arrays,function,memory,pass-by-reference,C,Arrays,Function,Memory,Pass By Reference,在本例中,问题是如何正确分配/释放内存: void test(char*** array, int* count) { *array = malloc(sizeof(char*) * MAX_ARRAY); while (...) { (*array)[i] = (char*)malloc(strlen(fooString)); } } 函数的调用: char** array; int count; test(&array, &count); // now

在本例中,问题是如何正确分配/释放内存:

void test(char*** array, int* count) {

  *array = malloc(sizeof(char*) * MAX_ARRAY);
  while (...) {
    (*array)[i] = (char*)malloc(strlen(fooString));
  }
}
函数的调用:

char** array;
int count;
test(&array, &count);
// now free the memory - i think i have to?
for(i = 0; i < count; i++) {
  free(array[i]); // <-- crash here
}
free(array);
char**数组;
整数计数;
测试(&数组,&计数);
//现在释放记忆-我想我必须?
对于(i=0;i免费(数组[i]);//针对您的特定问题:

您将
(*array)[i]
这是一个
char*
分配给
strlen(fooString)
,它通常相当于
sizeof(char)*strlen(fooString)
:这很容易出错。在这种情况下,您应该使用
sizeof(*(*array)[i])
,以确保不会错过正确的类型

要释放它,请从
i=0
循环到
i
并调用
free(ARRAY[i])
您在代码中用什么来代替
非常重要

一般来说在分配内存时,请确保尊重以下一般理念:

  • 如果一个函数分配内存,它会释放它自己,除非以后需要它
  • 如果一个函数在以后分配外部所需的内存,它只会这样做
这允许更好的代码体系结构和更容易释放内存

例如:

第一点:

void foo()
{
  char *a;

  a = malloc(sizeof(*a) * 5);
  a[0] = 'a';
  a[1] = 'b';
  a[2] = 'c';
  a[3] = 'd';
  a[4] = 0; //or '\0' if you prefer
  do_something_cool(a);
  free(a);
}
函数
foo
分配内存、处理内存并释放内存

第二点:

char *halfstrdup(char *str)
{
  int len;
  int i;
  char *newstr;

  len = strlen(str);
  newstr = malloc(sizeof(*newstr) * len / 2)
  for (i = 0; i < len; i++)
  {
    if ((i % 2) == 0)
      newstr[i / 2] = str[i];
  }
  return (newstr);
}

void foo2()
{
  char *half;

  half = halfstrdup("Hello, world !");
  do_something_cooler(half);
  free(half);
}
char*halfstrdup(char*str)
{
内伦;
int i;
char*newstr;
len=strlen(str);
newstr=malloc(sizeof(*newstr)*len/2)
对于(i=0;i
函数
halfstrdup
只分配和设置您需要的内存并返回它,函数
foo2
通过使用
halfstrdup
分配内存,然后使用它并释放它

在丢失指针之前,不要忘记释放,例如从foo或foo2返回后,您将无法释放分配的内存。

而不是

void test(char*** array, int* count) {

  *array = malloc(sizeof(char*) * MAX_ARRAY);
  while (...) {
    (*array)[i] = (char*)malloc(strlen(fooString));
  }
}

这似乎有效

#include <stdio.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>

char fooString[256];

void test(char*** array, int count) 
{
  int i = 0;
  *array = malloc(sizeof(char*) * count);
  for (i = 0; i < count; ++i) 
  {
    (*array)[i] = malloc(strlen(fooString)+1);
  }
}

int main()
{
  char** array = NULL;
  int count = 100;
  int i = 0;
  test(&array, count);


  for(i = 0; i < count;++i) 
  {
    free(array[i]); 
  }
  free(array);    
  return 0;
}
#包括
#包括
#包括
#包括
字符字符串[256];
无效测试(字符***数组,整数计数)
{
int i=0;
*数组=malloc(sizeof(char*)*count);
对于(i=0;i
不适用于您的问题,但不要强制转换测试中malloc()数组[0]的返回值与测试之外的数组[0]的返回值不同。在测试中,数组保存了函数调用测试中被调用数组的变量的地址。我还认识到这是两个不同的数组[0](仍然不理解为什么),但我如何才能释放分配的内存?另一个注意:
strlen
不包括“\0”字符。while(…)这是什么
?谢谢你的长篇大论,但这并不能解决我的问题。它如何解决你的问题?你至少看过我答案的第一部分了吗?我的问题是引用调用分配,我无法再次释放它。第一个示例:同一个函数中的所有内容。第二个示例:返回值。没有引用调用。有在C中没有“引用”这样的东西。传递给函数的是变量
数组
的地址,在那里存储
malloc
'd内存的地址,在那里存储其他malloc'd内存地址。必须首先释放第一个分配的内存块中包含的指针,即数组“单元”.谢谢你的回答-仍然是同一个问题…无法释放函数外的内存谢谢你,到目前为止,你的示例代码也在这里工作…但是我太笨了,看不出我的代码有什么不同。@claptrap你不需要将i初始化为0,for的
为你做了。@Eregrith我知道,这是一种反射;-)是的,我不能怪你^^
(*array)[i] = malloc(strlen(fooString) + 1)
#include <stdio.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>

char fooString[256];

void test(char*** array, int count) 
{
  int i = 0;
  *array = malloc(sizeof(char*) * count);
  for (i = 0; i < count; ++i) 
  {
    (*array)[i] = malloc(strlen(fooString)+1);
  }
}

int main()
{
  char** array = NULL;
  int count = 100;
  int i = 0;
  test(&array, count);


  for(i = 0; i < count;++i) 
  {
    free(array[i]); 
  }
  free(array);    
  return 0;
}