【发布时间】:2021-08-20 21:25:04
【问题描述】:
我正在尝试编写脚本文件来创建和提取 tarball。这是大学的代码,我是用 c 编程的新手。无论如何,我可以创建一个 tarball,顺便说一句,当我想提取时,由于 fclose 函数,问题就来了。一切似乎都正确,我找不到问题。 所有程序运行正常,但是当我尝试使用 fclose(tarFile) 关闭 tarFile 时,它给了我一条消息:
输出:
corrupted size vs. prev_size
Abortado (`core' generado)
通过调试,我发现问题出在哪里。当 header[i].size 在 readHeader 函数中的 for 循环中分配时,就会发生这种情况。
这个错误是我完成练习唯一需要解决的问题,因为来自 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), 1, 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;
}
【问题讨论】:
-
我认为你应该添加
loadstr函数的源代码;需要确保发布的答案是正确的(例如,我们需要知道它返回的字符串是否以空值结尾)。 -
@idz 不知道你为什么删除你的答案 - 'malloc(sizeof(str) + 1);'在我看来也很可疑(str 是一个指针)。
-
看来
readHeader可能混淆了nFiles和nrFiles?您从文件中读取了nrFiles,但随后您根据*nFiles为header分配空间,该空间尚未修改且仍为零。无论如何,拥有两个具有如此相似名称的变量可能是个坏主意。 -
@MartinJames 因为我认为可能还有其他事情正在发生,如果没有
loadstr来源,很难确定。 OP 附加一个 null 的事实可能意味着str我们没有以 null 结尾,然后strlen不是解决方案;loadstr需要修改。我的意思是sizeof(str)肯定是错误的,但这只是部分答案。 -
好的,伙计们。我发布了loadstr函数,谢谢大家的回复