如何解决损坏的大小与 prev_size Abortado (`core' generado) 函数 fclose
我正在尝试使用脚本文件来创建和提取 tarball。这是大学的代码,我是用 c 编程的新人。无论如何,我可以创建一个 tarball,顺便说一下,由于 fclose 功能,当我想提取时问题就出现了。一切似乎都正确,但我找不到问题所在。 所有程序都运行正常,但是当我尝试使用 fclose(tarFile) 关闭 tarFile 时,它给了我这个消息:
输出:
corrupted size vs. prev_size
Abortado (`core' generado)
通过调试我发现问题出在哪里。它发生在在 for 循环中的 readHeader 函数内部分配 header[i].size 时。
这个错误是我完成练习唯一需要解决的问题,因为来自 tarball 的数据被正确复制,但关闭 de tarFile 很重要,所以我感谢任何类型的帮助。
非常感谢,如果我能解释得更好,我很抱歉。这是我在 stackoverflow 上的第一篇文章,英语不是我的母语。
这是代码
/** Extract files stored in a tarball archive
*
* tarName: tarball's pathname
*
* On success,it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE.
* (macros defined in stdlib.h).
*
* HINTS: First load the tarball's header into memory.
* After reading the header,the file position indicator will be located at the
* tarball's data section. By using information from the
* header --number of files and (file name,file size) pairs--,extract files
* stored in the data section of the tarball.
*
*/
int
extractTar(char tarName[])
{
//1. Load Headers
FILE* tar = NULL;
tar = fopen(tarName,"r");
if(tar == NULL){
printf ("Error al abrir el tarball\n");
return EXIT_FAILURE;
}
printf("ADDRES INIT: %p\n",&tar);
int nFiles = 0;
stHeaderEntry* header = NULL;
//Carga el header y nFiles
header = readHeader(tar,&nFiles);
if(header == NULL || nFiles <= 0){
printf("Error al crear header // NUM FILES: %d\n",nFiles);
return EXIT_FAILURE;
}
printf("copiando...\n");
//3. copia de datos
//Para este punto el tar debería apuntar a la sección de datos
//por lo que se podría pasar a copiar los datos en función
//del header anteriormente cargado
FILE* output = NULL;
for(int i = 0; i < nFiles; i++){
output = fopen(header[i].name,"w");
if(output == NULL){
printf("Error al abrir output\n");
return EXIT_FAILURE;
}
int n = copynFile(tar,output,header[i].size);
if(n == -1){
printf("Error al copìar los datos en output\n");
return EXIT_FAILURE;
}
if(fclose(output) != 0){
printf("Error al cerra output\n");
return EXIT_FAILURE;
}
}
printf("LLAMADA A FREE\n");
//-------------FREE_MEMORY-----------------------//
printf("%s\n",header[0].name);
for(int i = 0; i < nFiles; i++){
printf("FREE HEADER NAME\n");
free(header[i].name);
header[i].name = NULL;
}
printf("FREE HEADER\n");
free(header);
printf("CLOSE TAR\n");
printf("ADDRES END: %p\n",&tar);
if(fclose(tar) != 0){
printf("Fallo al cerrar tarFile\n");
return EXIT_FAILURE;
}
printf("Extracción realizada con éxito\n");
return EXIT_SUCCESS;
}
- readHeader 函数
/** Read tarball header and store it in memory.
*
* tarFile: pointer to the tarball's FILE descriptor
* nFiles: output parameter. Used to return the number
* of files stored in the tarball archive (first 4 bytes of the header).
*
* On success it returns the starting memory address of an array that stores
* the (name,size) pairs read from the tar file. Upon failure,the function returns NULL.
*/
stHeaderEntry*
readHeader(FILE * tarFile,int *nFiles)
{
int nrFiles = 0;
//Lectura de nFiles
if((fread(&nrFiles,sizeof(int),1,tarFile)) != 1){
printf("Error al leer nFiles\n");
return NULL;
}
//Reserva de memoria en función de nFiles
stHeaderEntry* header = malloc(sizeof(stHeaderEntry) * (*nFiles));
//Lectura de los datos del header
char* str = NULL;
int size = 0;
for(int i = 0; i < nrFiles; i++){
//Primero el nombre
str = loadstr(tarFile);
if(str == NULL){
return NULL;
}
header[i].name = malloc(sizeof(str) + 1);
header[i].name = strcpy(header[i].name,str);
header[i].name = strcat(header[i].name,"\0");
//Segundo los bytes del archivo
int n = fread(&size,sizeof(unsigned int),tarFile);
if(n != 1){
printf("Error al leer header size\n");
return NULL;
}
header[i].size = size;
}
//Carga completa
printf("READHEADER SUCCESSFUL\n");
(*nFiles) = nrFiles;
return header;
}
解决方法
在您的 readHeader
函数中,您按如下方式为字符串分配空间:
header[i].name = malloc(sizeof(str) + 1);
这将使用 str
的大小,一个字符串指针,它是一个常数值,取决于系统指针的大小(通常是 4 或 8);这不是你想要的。
您应该使用 strlen
来计算 str
指向的 C 字符串的长度。
header[i].name = malloc(strlen(str) + 1);
loadstr
中也有问题,因为您只将一个字符读入缓冲区,您应该更改:
while((n = fread(buf,1,file)) != 0 && strcmp(buf,"\0") != 0){
length++;
}
到
while((n = fread(buf,file)) != 0 && buf[0] != '\0'){
length++;
}
否则 strcmp
可能正在读取未初始化的内存。
其他一些观察:
- 您实际上并不需要复制字符串,因为
loadstr
正在分配它,但是如果您这样做了,那么您还需要释放loadstr
的返回值。 - 您不需要在
strcpy
之后将字符串终止为空,它会为您完成。 - 阅读
strncpy
,它比strcpy
更安全。
- loadstr 包含这个
/** Loads a string from a file.
*
* file: pointer to the FILE descriptor
*
* The loadstr() function must allocate memory from the heap to store
* the contents of the string read from the FILE.
* Once the string has been properly built in memory,the function returns
* the starting address of the string (pointer returned by malloc())
*
* Returns: !=NULL if success,NULL if error
*/
char*
loadstr(FILE * file)
{
char* str = NULL;
char buf[1];
int length = 0;
int n = 0;
//Asignación del tamaño del buffer
while((n = fread(buf,"\0") != 0){
length++;
}
str = malloc(length + 1);
//Debido al while anterior,ahora file apunta a otro lado
//Hay que hacer un rewind
fseek(file,-(length + 1),SEEK_CUR);
//Se guarda el nombre en str
if(fread(str,length + 1,file) != 1){
printf("Error en loadstr\n");
return NULL;
}
return str;
}
我之前没有发帖是因为我认为没有必要。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。