试图在C - malloc,realloc和free中学习正确的内存处理

时间:2012-02-26 17:15:29

标签: c malloc free realloc

所以我有两个(希望很快)的问题。我想我已经掌握了使用malloc来节省数据空间的问题,但是realloc会造成麻烦。在下面的代码中,我有一个包含8个字符指针的数组 - 它应该填满 - 我正在尝试扩展为另一个 8个字符指针(然后是另外8个,依此类推)。 Realloc第一次执行此操作(即,它将扩展数组一次),但之后我收到以下错误:

*** glibc detected *** ./a.out: realloc(): invalid next size:

据我所知,一切都没有改变。为什么realloc会在8的数组上工作,而不是在16的数组上工作?

我的第二个问题是内存泄漏。我仍然不确定我需要在程序中释放什么。其他人告诉我,inputcpy需要被释放。这都在这里吗?另外,我想在程序的哪个阶段释放它?

#define DEBUG 1

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char ** getArgs( char *input,  char **args, int ct);
char ** args;

int main(int argc, char* argv[]) {
  char input[]="echo arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13";
  char inputcpy[strlen(input)];
  strcpy(inputcpy, input);
  char * prog=strtok(input, " ");

  /*Saving space for an array of 8 strings*/
  args=( char **) calloc(8, sizeof( char *));  

  getArgs(inputcpy, args, 1);

  if(DEBUG) {
    printf("arg address after: %p\n", args);
  }

  int q;
  int pid=fork();
  if (pid==0) {
    execvp(prog, args); 
    return 0;
  }
  else {
    int status=0;
    wait(&status);
  }
}

char ** getArgs( char *input,  char **args, int ct) {
  int adj=(ct-1)*8;//if we recurse, this ensures correct indexes are used
  char *inputcpy=malloc(strlen(input));
  strcpy(inputcpy, input);

  /*Initialize indexes/Prepare for copying*/
  int i; 
  if(ct==1) {
    i=1;
    args[0]=" "; //quick hack to ensure all args are used by exec()
  }
  else
    i=0;

  /**Actually do the copying now**/
  char *temp=strtok(NULL, " ");
  args[adj+i++]=temp;
  while (temp != NULL && i<8) {
    temp=strtok(NULL, " ");
    args[adj+i++]=temp;
  }   

  /*If there are more args than we have room for*/
  if(i>=8){
    /*Increase the array to store 8 more strings*/
    args= (char **) realloc(args, sizeof(args)+8*sizeof(char *) );
    getArgs(inputcpy, args, (++ct) );
  }   

  return NULL;
}

2 个答案:

答案 0 :(得分:2)

 char *inputcpy=malloc(strlen(input));
 strcpy(inputcpy, input);

你没有为你的字符串分配足够的空间,应该是:malloc(strlen(input) + 1);

同样在这里:

 char inputcpy[strlen(input)];
 strcpy(inputcpy, input);

字符串是一系列终止的字符,包含空字符,字符串的长度是空字符前面的字符数。

您还错误地使用realloc

args= (char **) realloc(args, sizeof(args)+8*sizeof(char *) );

此用途中存在潜在的内存泄漏。

关于free,您应该做的很简单:每个malloc都应该有相应的free

答案 1 :(得分:0)

我会回答你的最后一个问题: 另外,我想在程序的哪个阶段释放它?

嗯,建议您在调用malloc的函数返回之前释放它。如果你这样做,你就不必担心后面的任何内存泄漏。

但是,在你的case main中,调用函数也可以在你的getArgs()函数完成时调用free()并将控制权返回给main。这是因为可以使用带有free()的不同指针变量;你只需要确保新指针存储相同的地址。