我有一个
*** glibc detected *** [...] free(): invalid pointer: 0x0804d0d0 ***
在这个函数中:
ptrGBloque determinar_nodo(const char* path){
// Si es el directorio raiz, devuelve 0:
if(!strcmp(path, "/")) return 0;
int fd, i, nodo_anterior, aux;
// Super_path usado para obtener la parte superior del path, sin el nombre.
char *super_path = (char*) malloc(strlen(path)), *nombre = (char*) malloc(strlen(path));
char *start = nombre, *start_super_path = super_path; //Estos liberaran memoria.
struct grasa_file_t *node, *inicio;
unsigned char *node_name;
strcpy(super_path, path);
strcpy(nombre, path);
// Obtiene y acomoda el nombre del archivo.
if (lastchar(path, '/')) {
nombre[strlen(nombre)-1] = '\0';
}
nombre = strrchr(nombre, '/');
nombre[0] = '\0';
nombre = &nombre[1]; // Acomoda el nombre, ya que el primer digito siempre es '/'
// Acomoda el super_path
if (lastchar(super_path, '/')) {
super_path[strlen(super_path)-1] = '\0';
}
aux = strlen(super_path) - strlen(nombre);
super_path[aux] = '\0';
nodo_anterior = determinar_nodo(super_path);
// Abrir conexion y traer directorios, guarda el bloque de inicio para luego liberar memoria
if ((fd = open(DISC_PATH, O_RDONLY, 0)) == -1) {
printf("ERROR");
return -ENOENT;
}
node = (void*) mmap(NULL, HEADER_SIZE_B + BITMAP_SIZE_B + NODE_TABLE_SIZE_B , PROT_READ, MAP_SHARED, fd, 0);
inicio = node;
node = &(node[GFILEBYBLOCK + BITMAP_BLOCK_SIZE]);
// Busca el nodo sobre el cual se encuentre el nombre.
node_name = &(node->fname[0]);
for (i = 0; ( (node->parent_dir_block != nodo_anterior) | (strcmp(nombre, (char*) node_name) != 0) | (node->state == 0)) & (i < GFILEBYTABLE) ; i++ ){
node = &(node[1]);
node_name = &(node->fname[0]);
}
// Cierra conexiones y libera memoria.
free(start);
free(start_super_path);
if (munmap(inicio, HEADER_SIZE_B + BITMAP_SIZE_B + NODE_TABLE_SIZE_B) == -1) printf("ERROR");
close(fd);
if (i >= GFILEBYTABLE) return -1;
return (i+1);
}
当我用以下函数调用此函数时会出现问题:
determinar_nodo("/Otra Carpetita/Inside Otra/Inside Otra Otra :D/");
由于重新布局,代码中有许多冗余步骤,只是尝试将它们移除。
对我来说真正重要的是记忆问题。请注意,在声明的开始时,我创建了start和start_super_path指针,而不是在函数结束时松开地址以释放。
此外,似乎该函数在第二次调用时会中断。这意味着第一个“免费”工作正常,与determinar_nodo("/Otra Carpetita/")
的调用相对应,但它在没有通话determinar_nodo("/Otra Carpetita/Inside Otra/")
的情况下中断。
在内存浏览器上进行补偿,我注意到该函数试图释放的地址确实是正确的,所以我真的不知道会发生什么。 无论如何,如果我释放任何这些,我得到了上述错误。
先谢谢你的帮助,请原谅我可怜的英语。
答案 0 :(得分:3)
您必须拥有(char*) malloc(strlen(path)+1)
(\ 0终止字符为+1)。
否则,您将有缓冲区溢出,这可能会破坏堆。
相关链接:How do malloc() and free() work?