Обнаружен glibc (ошибка памяти) при вставке в std :: map - PullRequest
0 голосов
/ 11 марта 2011

У меня есть следующий код:

struct VRfile{    
    char sessionID[10];    
    char file[20];    
    int first;    
};    

std::map (int ,struct VRfile *) maps;
struct VRfile *vrinfo = (struct VRfile*)malloc (sizeof(struct VRfile*));
 strcpy(vrinfo->sessionID, sessionId.c_str());  
  strcpy(vrinfo->file, filename.c_str());  

 socketmap.insert(std::pair(int , struct VRfile *) (thisfd,vrinfo));

Я получаю сообщение об ошибке в строке socketmap.insert(std::pair(int , struct VRfile *) (thisfd,vrinfo));:

Error: *** glibc detected *** memory corruption: 0x080aa7b0 ***  
/lib/libc.so.6[0x6222dd]  
/lib/libc.so.6(__libc_malloc+0x67)[0x623e97]  
/usr/lib/libstdc++.so.6(_Znwj+0x27)[0x45d7ab7]  

backtrace:  
0  0x002eb402 in __kernel_vsyscall ()  
1  0x005e0df0 in raise () from /lib/libc.so.6  
2  0x005e2701 in abort () from /lib/libc.so.6  
3  0x0061928b in __libc_message () from /lib/libc.so.6  
4  0x006222dd in _int_malloc () from /lib/libc.so.6  
5  0x00623e97 in malloc () from /lib/libc.so.6  
6  0x045d7ab7 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6  

Затем он указывает на строку кода, которую я упомянул выше. Никто не может сказать мне, почему это происходит?

Ответы [ 2 ]

2 голосов
/ 11 марта 2011

Вы не выделяете достаточно места для своей структуры - вы только выделяете ценность указателя (4 или 8 байт, в зависимости от размера указателя), когда на самом деле вы должны располагать где-то порядка 36 байтов ( в частности, sizeof(VRfile). Итак, вы топаете кучу, записывая в нее случайные значения (так называемое переполнение кучи ), что приводит к путанице в структурах данных, используемых malloc для отслеживания памяти. Когда он обнаруживает это повреждение, он поднимает руки и завершает вашу программу.

Однако, поскольку это C ++, а не C, вам действительно следует использовать operator new вместо malloc для выделения динамической памяти. Вам не нужно иметь дело с размером памяти, которую вы выделяете, это подразумевается в типе переменной. Во-вторых, нет причины всегда говорить struct VRfile вместо просто VRfile - это необходимо только в простом C-коде (не C ++), и только тогда, когда нет правильного typedef (который обычно есть).

Итак, просто напишите это:

VRfile *vrinfo = new VRfile;

И, конечно, когда вы удаляете свою карту (или удаляете с нее любой элемент), обязательно удалите каждое значение в ней, чтобы избежать утечки памяти. Например:

// This could also be implemented using a functor and std::for_each
for(std::map<int, VRfile*>::iterator iter = maps.begin(); iter != maps.end(); ++iter)
    delete iter->second;
maps.clear();
1 голос
/ 11 марта 2011

При вызове malloc вы выделяете достаточно памяти для указателя на VRfile вместо VRfile (возможно, просто опечатка).

VRfile *vrinfo = (VRfile*)malloc(sizeof(VRfile));

Обратите внимание, что в C ++ вам не нужно использовать struct при ссылке на тип.

...