2013-10-04 140 views
0

我目前正在編寫一個程序,它在某些時候需要將所有文件的大小存儲在數組中的特定文件夾中。我的程序在發佈模式下在Code :: Blocks上運行時崩潰,但在調試模式下運行。它也在Mac OS上的XCode上運行時沒有任何問題。下面的代碼:程序只在C :: B調試模式下運行

#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, &currentSize); 
     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, &currentSize); 
     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

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)時,你不需要任何更多

+0

哦,我的上帝,我太忙發現了一些複雜的問題用的fopen,我沒」甚至不必考慮正確的內存分配。非常感謝你! – user2846499

相關問題