释放内存(或分配)时出现问题

时间:2019-02-21 02:12:12

标签: c gdb malloc

我收到一条“ free():无效的指针,异常终止(内核已转储)”的消息,可能会跟踪到我正在执行的free操作。

"C:\Program Files\Amazon\AWSCLI\bin\aws.exe" deploy create-deployment --application-name App.Web --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name Development-Staging-UAT --region us-west-2 --description "App.Web" --s3-location bucket=app-artifacts,bundleType=zip,key=development/Publish.zip

因此,我在arrayOfWords函数中为每个用新行字符分隔的“单词”分配内存。在打印完主函数中的所有单词之后,我首先尝试释放分配给每个单词的内存,然后希望释放指针本身。当我尝试在gdb中调试该指针时,我在for循环处设置了一个断点,试图释放每个引用。在第二次迭代期间我得到了一个SIGABRT,我对此为何感到困惑。 因此,当我尝试释放for循环中的内容时以及在释放实际指针之前就发生了错误。

干杯。

2 个答案:

答案 0 :(得分:1)

各种麻烦,但我认为char *temp = strtok(NULL, "\n");是主要的罪魁祸首。

strtok(str, "\n");将相邻的"\n\n"折叠成一个令牌,后来for (int i = 0; i < newLines; i++) { free((ret[i])); }试图释放newLines行,即使仅分配了count行。

代码也可能会错误地尝试释放"\0"

其他麻烦

文件的结尾可能不是'\n',因此newLineCounter偏离了一个。

如果文件包含空字符,则newLineCounter()太小。


其他花絮

检查fseek(), ftell(), malloc()的返回值

避免静音大小截断。 ftell()返回longstrlen()返回size_t


一些 unested 替代代码:

读取文件

char *read_file(FILE *f, size_t *sz) {
  if (fseek(f, 0, SEEK_END)) return NULL;
  long len = ftell(handler);
  // If trouble finding the end or file too big ...
  if (len == -1 || (unsigned long) len >= SIZE_MAX) return NULL;

  *sz = len;
  rewind(handler);

  char *buffer = malloc(sizeof *buffer * (*sz + 1));
  size_t read_size = fread(buffer, sizeof *buffer, *sz, f);

  // Reading less than expected is not certainly wrong as the 
  // ftell technique is not _the_ best way to find file size,
  // It may overstate.
  // More robust code would use another approach.

  buffer[read_size] = '\0'; 
  *sz = read_size;
  return buffer;
}

计数行

size_t newLineCounter(const char *mem, size_t sz) { 
  size_t count=0;
  for(size_t i=0; i < sz; i++) {
    count += mem[i] == '\n';
  }
  if (i > 0 && mem[sz-1] != '\n') count++;
  return count;
}

线阵

char **arrayOfLines(char *str, size_t sz, size_t line_count) {
  char **lines = malloc(sizeof *lines * (line_count + 1));
  if (lines == NULL) return NULL;

  for(size_t i=0; i < line_count; i++) {
    const char *eol = memchr(str, '\n', sz);
    size_t len;
    if (eol == NULL) {
      len = sz;
    } else {
      len = (size_t)(eol - str + 1);
    }
    lines[i] = malloc(len + 1);
    if (lines[i]) {
      memcpy(lines[i], str, len);
      lines[i][len] = '\0';
    }
    str += len;
    sz -= len;
  }
  lines[line_count] = NULL;
  return lines;
}

答案 1 :(得分:1)

您在函数malloc中使用char ** arrayOfWords(char *str,int max)时遇到问题

1>对于函数**s中的双指针char ** arrayOfWords(char *str,int max)

s=malloc(max*(sizeof(char *)+1));

应该是

s=malloc(max*sizeof(char *));

因为s是指向char指针数组的指针。

2>对于**s中的每个项目。

s[0]=malloc((sizeof(char *)*(size+1)));
s[count]=malloc((sizeof(char *)*(size+1)));

应该是

s[0]=malloc((sizeof(char)*(size+1));
s[count]=malloc((sizeof(char)*(size+1)));

因为s [i]现在是指向字符数组的指针。