我的函数有问题。
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++) = ' ';
*size = j;
return fnName;
}
我给这个函数添加了一个字符串,读起来很好,但我在一个循环中运行这个函数,在第三次迭代中,这一行被压垮了:
fnName = (char *)malloc(nameBuffer);
我在netbeans调试器中收到一条消息:
malloc(): memory corruption: 0x08a62218
我用netbeans和lubuntu。
您发布的代码没有问题。运行时错误消息指示程序早期可能存在堆损坏,稍后对*alloc
函数的调用显示了这一点。
试着在整个程序上运行valgrind,它可能会找到一些东西。如果做不到,请仔细检查使用malloc缓冲区的代码,以确保它不会溢出缓冲区。你可能需要分而治之才能弄清楚程序的哪一部分有问题。
fnName = (char *)realloc(fnName, nameBuffer);
realloc通过为您重新分配更多内存来扩展您的内存。如果您要求的额外内存无法在旧fnName内存所在的同一连续区域中提供,分配器将从内存中的另一个位置获取您的分配块。这意味着,所有仍然指向旧fnName内存区域的指针(例如,另一个指向
*(fnName + N)
的指针(仍然指向那里,即使分配器为fnName提供了一个新地址,以便您可以拥有所请求的所有内存。这些指针被称为悬空指针,因为它们指向程序不再拥有的已分配内存。这就是您收到"内存损坏"消息的原因。操作系统告诉你,你的程序试图访问它不拥有的内存。当程序使用这些悬空指针时,就会发生这种情况,就好像它们仍然指向已分配的内存一样。realloc工作正常,除非您要求的内存超过分配器从当前地址连续提供的内存。如果它不能连续提供内存,它会从其他地方获取内存,并向您返回另一个内存地址。
要解决此问题,必须将所有仍引用旧内存的指针重新分配给新内存地址。由于您无法真正预测何时需要这样做,也不想编写不必要的代码,而且C没有类,因此您应该在程序开始时考虑分配足够大的内存池。然后,您可以编写一个简单的分配/取消分配算法,允许您在执行函数时从中获取内存。这样做将教会您更多关于分配连续内存的知识。
char*池;if((pool=malloc(sizeOfPoolInBytes((==NULL(merror((
- 看看下面修改后的函数:
#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] = ' ';
char* newString = NULL;
int newStringSize = 0;
int* ptrSize = &newStringSize;
newString = readFnName(string, n, 0, ptrSize);
for(int i = 0; i < n; i++){
printf("%cn", string[i]);
}
printf("n");
for(int j = 0; j < *(ptrSize); j++){
printf("%cn", newString[j]);
}
free(string);
free(newString);
return 0;
}