我目前正在编写一个程序,在某些时候需要将所有文件的大小存储在数组中的特定文件夹中。我的程序在发布模式下在Code :: Blocks上运行时崩溃,但是在调试模式下运行。它在Mac OS上的XCode上也没有任何问题。这是代码:
#define MALLOC_ERROR -1
#define DIR_ACCESS_ERROR -2
#define FILE_ACCESS_ERROR -3
#define FILE_OPEN_ERROR -4
#define OUTPUT_FILE_OPEN_ERROR -5
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
int compare(const void*, const void*);
int getFileSizeMarginNumbers(char[], int, unsigned long int*);
int main(void){
FILE *out;
int n;
int i, count = 1;
unsigned long int *fileSizeMarginNumber;
char directoryName[] = "C:\\Users\\Борис\\Desktop\\new\\";
char outputFilePath[] = "C:\\Users\\Борис\\Desktop\\out.txt";
printf("Enter number of files in directory:");
scanf("%d", &n);
if (!(fileSizeMarginNumber = (unsigned long int*)malloc(n*sizeof(unsigned long int)))){
printf("Not enough memory");
return MALLOC_ERROR;
}
switch (getFileSizeMarginNumbers(directoryName, n, fileSizeMarginNumber)) {
case MALLOC_ERROR:
return MALLOC_ERROR;
break;
case DIR_ACCESS_ERROR:
return DIR_ACCESS_ERROR;
break;
case FILE_ACCESS_ERROR:
return FILE_ACCESS_ERROR;
break;
case FILE_OPEN_ERROR:
return FILE_OPEN_ERROR;
break;
}
qsort(fileSizeMarginNumber, n, sizeof(unsigned long int), compare);
if (!(out = fopen(outputFilePath, "w"))){
printf("Unable to open output file");
return OUTPUT_FILE_OPEN_ERROR;
}
for (i=1; i<n; ++i) {
if (fileSizeMarginNumber[i] == fileSizeMarginNumber[i - 1])
++count;
else{
fprintf(out, "%ldKB - %ldKB: %d file(s);\n", (fileSizeMarginNumber[i - 1] - 1)*16, fileSizeMarginNumber[i - 1]*16, count);
count = 1;
}
}
fprintf(out, "%ldKB - %ldKB: %d files;\n", (fileSizeMarginNumber[i - 1] - 1)*16, fileSizeMarginNumber[i - 1]*16, count);
return 0;
}
int getFileSizeMarginNumbers(char directoryName[], int n, unsigned long int *fileSizeMarginNumber){
int i, fileDescriptor;
struct dirent *file;
struct stat currentSize;
DIR *directory;
FILE *buf;
if (!(directory = opendir(directoryName))) {
printf("Unable to get access to the specified directory");
return DIR_ACCESS_ERROR;
}
for (i=0;i<2;++i){
if (!(file = readdir(directory))) {
printf("Unable to get access to a file in the specified directory");
return FILE_ACCESS_ERROR;
}
}
for (i=0; i<n; ++i) {
if (!(file = readdir(directory))) {
printf("Unable to get access to a file in the specified directory");
return FILE_ACCESS_ERROR;
}
printf("%s", strcat(strdup(directoryName), file->d_name));
if (!(buf = fopen(strcat(strdup(directoryName), file->d_name), "r"))){
printf("Unable to process a file in the specified directory");
return FILE_OPEN_ERROR;
}
fileDescriptor = fileno(buf);
fstat(fileDescriptor, ¤tSize);
fileSizeMarginNumber[i] = (unsigned long int)truncl(currentSize.st_size/(1024*16)) + 1;
fclose(buf);
}
return 0;
}
int compare(const void *a, const void *b){
if ((*(long int*)a - *(long int*)b) < 0)
return -1;
else if ((*(long int*)a - *(long int*)b) == 0)
return 0;
else
return 1;
}
问题似乎位于以下块中:
for (i=0; i<n; ++i) {
if (!(file = readdir(directory))) {
printf("Unable to get access to a file in the specified directory");
return FILE_ACCESS_ERROR;
}
printf("%s", strcat(strdup(directoryName), file->d_name));
if (!(buf = fopen(strcat(strdup(directoryName), file->d_name), "r"))){
printf("Unable to process a file in the specified directory");
return FILE_OPEN_ERROR;
}
fileDescriptor = fileno(buf);
fstat(fileDescriptor, ¤tSize);
fileSizeMarginNumber[i] = (unsigned long int)truncl(currentSize.st_size/(1024*16)) + 1;
fclose(buf);
}
该程序应该逐步打开文件夹中的所有文件。但是,对fopen的第二次或第三次调用有时会触发以下异常:
Program received signal SIGSEGV, Segmentation fault.
In ntdll!RtlLargeIntegerToChar () (C:\Windows\system32\ntdll.dll)
我不明白这依赖于我运行程序的位置,我会非常感谢你的帮助。
非常感谢你。
答案 0 :(得分:0)
strcat()
中的fopen()
不正确:
strcat(strdup(directoryName), file->d_name)
首先strdup()
分配strlen(directoryName)+1
字节和副本directoryName
,然后strcat()
想要file->d_name
附加到该副本。但由于没有分配额外的空间,可能会发生seg故障。做一些类似的事情:
char *pathname = MALLOC( strlen(directoryName) + strlen(file->d_name) + 1 );
strcpy( pathname, directoryName );
strcat( pathname, file->d_name );
当你不再需要它时,别忘了free(pathname)