realloc:下一个大小和malloc无效:内存损坏(快)

use*_*694 3 c realloc

我正在做一个K和RC编程书的乐趣练习.该程序用于从用户输入的一组行中查找最长行,然后打印它.

输入:

This is a test

This is another long test

this is another long testthis is another long test
Run Code Online (Sandbox Code Playgroud)

观察:

它对前两个输入运行正常,但对于较大的字符串(第三个输入)则失败

错误:

Error in `./longest': realloc(): invalid next size: 0x000000000246e010 ***
Error in `./longest': malloc(): memory corruption (fast): 0x000000000246e030 ***
Run Code Online (Sandbox Code Playgroud)

我的努力:

我一直试图调试这个2天(橡皮鸭调试),但逻辑似乎很好.GDB指向_getline函数中的realloc调用,并在顶部显示glibc.so内存分配调用的大量回溯.

这是我写的(部分,部分内容直接取自本书): -

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

int MAXLINE =  10;
int INCREMENT = 10;

char* line = NULL, *longest = NULL;

void _memcleanup(){
    free(line);
    free(longest);      
}

void copy(char longest[], char line[]){
    int i=0;
    char* temp = realloc(longest,(MAXLINE)*sizeof(char));
    if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
    }
    longest = temp;

    while((longest[i] = line[i]) != '\0'){
        ++i;
    }    
}

int _getline(char s[]){
  int i,c;
  for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){
    if(i == MAXLINE - 1){
      char* temp = realloc(s,(MAXLINE + INCREMENT)*sizeof(char));
      if(temp == NULL){
        printf("%s","Unable to allocate memory");
        _memcleanup();
        exit(1);
      }

      s= temp;
      MAXLINE += INCREMENT;
    }
    s[i] = c;
  }

  if(c == '\n'){
      s[i++] = c;
  }

  s[i]= '\0';

  return i;
} 

int main(){
  int max=0, len;

  line = malloc(MAXLINE*sizeof(char));
  longest = malloc(MAXLINE*sizeof(char));

  while((len = _getline(line)) > 0){
    printf("%d%d", len, MAXLINE);
    if(len > max){
      max = len;
      copy(longest, line);
    }
  }
  if(max>0){
    printf("%s",longest);
  }

  _memcleanup();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

dev*_*fan 5

您在复制的地址上重新分配(因为参数).
C中的参数是每次原始值的副本; 在
指针的情况下,它将指向相同的位置,但地址本身被复制.

realloc调整与地址相关的缓冲区大小,到目前为止一切正常.
但它可以重新定位整个事物并分配一个全新的地址,
这个新地址(如果它发生)将在函数返回main后丢失.

使用双指针:
传递a char **s而不是char *s(== char s[])作为形式参数,
传递作为实际值的&xyzintead xyz,并在函数内部,
使用*xyz**xyz(或(*xyz)[index])作为地址和值.

其他事情:
全局变量是丑陋的(当命名与参数相同时会令人困惑),
乘以sizeof(char)是无意义的,因为它每次都是1,
并且大写中的名称应该用于#define而不是变量.