C malloc函数抛出内存错误

时间:2014-05-11 21:39:50

标签: c linux malloc

我的功能有问题。

char *readFnName(char *fnString, int n, int offset, int *size) {
    char *fnName;
    int nameBuffer, i, j;

    i = offset;
    j = 0;
    nameBuffer = 8;
    fnName = (char *)malloc(nameBuffer);

    while(*(fnString + i) != '(' && i<n) {
        *(fnName + j++) = *(fnString + i++);
        if (j>=nameBuffer) {
            nameBuffer += 8;
            fnName = (char *)realloc(fnName, nameBuffer);
        }
    }

    *(fnName + j++) = '\0';
    *size = j;

    return fnName;
}

我将这个函数添加为一个字符串,这是很好的读取,但是我在循环中运行这个函数,并且在第3次迭代中,这行被粉碎了:

fnName = (char *)malloc(nameBuffer);

我在netbeans调试器中收到一条消息:

malloc(): memory corruption: 0x08a62218

我使用netbeans和lubuntu。

2 个答案:

答案 0 :(得分:1)

您发布的代码没有问题。运行时错误消息表明程序中可能早先存在堆损坏,稍后调用*alloc函数会显示堆损坏。

尝试在整个程序上运行valgrind,它可能会找到一些东西。如果做不到这一点,请仔细检查使用malloc缓冲区的代码,以确保它不会溢出它们。您可能需要分而治之以找出程序的哪个部分存在问题。

答案 1 :(得分:1)

 fnName = (char *)realloc(fnName, nameBuffer);
  1. realloc 通过为您重新分配更多内存来扩展您的内存。如果您要求的额外内存不能在旧的fnName内存所在的相同连续区域中给出,则分配器将从内存中的另一个位置获取分配块。这意味着仍然指向旧fnName内存区域的所有指针(例如指向*(fnName + N)的另一个指针)仍指向那里,即使分配器为您提供了fnName的新地址,这样您就可以拥有所有您请求的内存。那些指针被称为悬空指针,因为它们指向程序不再拥有的解除分配的内存。这就是为什么你会得到内存损坏&#34;信息。操作系统告诉您,您的程序试图访问它不拥有的内存。当你的程序使用那些悬空指针时,就好像它们仍指向已分配的内存一样。

  2. realloc 正常工作,除非您要求的内存多于分配器可以从您当前的地址连续提供的内存。如果它无法连续提供内存,它将从其他地方获取并返回另一个内存地址。

  3. 要解决此问题,您必须重新分配仍然引用重新分配给新内存地址的旧内存的所有指针。既然您无法预测何时需要执行此操作并且您不想编写不必要的代码,并且由于C没有类,那么您应该考虑在您的开头分配足够大的内存池。程序。然后你可以编写一个简单的分配/解除分配算法,允许你在函数中从中获取内存。这样做会教你更多关于分配连续内存的知识。

  4.     char* pool;
        if ((pool = malloc(sizeOfPoolInBytes)) == NULL)
          merror();
    1. 请看下面修改后的功能:
    2. #include<stdlib.h>
      #include<iostream>
      using namespace std;
      
      char* readFnName(char* fnString, int n, int offset, int* size){
        char *fnName = NULL;
        int nameBuffer = 8;
        int i = offset;
        int j = 0;
        int count = 0;
        int fnNameIndex = 0;
      
        //-------------------------------------------------------- Since you want to copy everything but '(' find out how 
        //-------------------------------------------------------- long fnString is without all the '(' characters.
        for( int k = 0; k < n; k++)
        {
          if( *(fnString + k) != '(' )
          {
            count += 1;
          }
        }
      
        //-------------------------------------------------------- Now, just allocate a string to store the result
        fnName = malloc(count);
      
        //-------------------------------------------------------- Now, copy everything but the '(' character
        for( int p = i; p < n; p++){
          if( *(fnString + p) != '(')
          {
            if(fnNameIndex < count)
              {
                *(fnName + fnNameIndex) = *(fnString + p);
                fnNameIndex++;
              }
          }
        }
      
        *size = fnNameIndex;//----------------------------------- This will give the accurate size in case the offset is not = 0
        return fnName;
      }
      
      int main(){
      
        char* string = NULL;
        int n = 5;
        string = malloc(n);
        string[0] = 'a';
        string[1] = 'b';
        string[2] = '(';
        string[3] = 'c';
        string[4] = '\0';
      
        char* newString = NULL;
        int newStringSize = 0;
        int* ptrSize = &newStringSize;
        newString = readFnName(string, n, 0, ptrSize); 
      
        for(int i = 0; i < n; i++){
          printf("%c\n", string[i]);
        }
      
        printf("\n");
      
        for(int j = 0; j < *(ptrSize); j++){
          printf("%c\n", newString[j]);
        }
      
        free(string);
        free(newString);
      
        return 0;
      }