函数调用后删除了指针内容,为什么?

时间:2016-02-08 00:04:01

标签: c pointers memory

我一直试图弄清楚我的代码发生了什么,但没有运气。我已经定义了一个指针:     char ** filesList = readDir(); 指针指向一个字符串数组。我能够在当前目录中拥有所有文件名。这不是问题。

当我传递filesList [i]时,对于任何i = 0,..,n:     readImage(filesList [I],...); filesList的内容被删除..我不知道为什么..有什么帮助吗?!

我的代码:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>

#include <jpeglib.h>

unsigned char *readImage(//struct jpeg_decompress_struct cinfo,
                         char *inputPath,
                         int *width,
                         int *height,
                         int *pixel_size)
{
    char *inputFilename;
    struct jpeg_decompress_struct cinfo;
    unsigned char *buffer;
    int rc, i, j;
    struct stat file_info;
    unsigned long jpg_size;
    unsigned char *jpg_buffer;

    struct jpeg_error_mgr jerr;
    int row_stride;

    inputFilename = (char *)malloc(1 + strlen(inputPath));
    strcpy(inputFilename, inputPath);

    rc = stat(inputFilename, &file_info);
    if (rc) {
        syslog(LOG_ERR, "FAILED to stat source jpg");
        exit(EXIT_FAILURE);
    }
    jpg_size = file_info.st_size;
    jpg_buffer = (unsigned char*) malloc(jpg_size + 100);

    int fd = open(inputFilename, O_RDONLY);
    i = 0;
    while (i < jpg_size) {
        rc = read(fd, jpg_buffer + i, jpg_size - i);
        i += rc;
    }
    close(fd);

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo); // <-- Exactly at this point, inputPath's content is erased ...

    jpeg_mem_src(&cinfo, jpg_buffer, jpg_size);

    rc = jpeg_read_header(&cinfo, TRUE);

    if (rc != 1) {
        syslog(LOG_ERR, "File does not seem to be a normal JPEG");
        exit(EXIT_FAILURE);
    }

    jpeg_start_decompress(&cinfo);
    *width = cinfo.output_width;
    *height = cinfo.output_height;
    *pixel_size = cinfo.output_components;

    unsigned long bmp_size = cinfo.output_width * cinfo.output_height * cinfo.output_components;
    buffer = (unsigned char*)malloc(bmp_size);

    row_stride = cinfo.output_width * cinfo.output_components;

    while (cinfo.output_scanline < cinfo.output_height) {
        unsigned char *buffer_array[1];
        buffer_array[0] = buffer + (cinfo.output_scanline) * row_stride;

        jpeg_read_scanlines(&cinfo, buffer_array, 1);
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    free(jpg_buffer);

    return buffer;
}

char **readDir(int *nof) {
    char **filesList;
    int numFiles = 0;
    int size = 256;
    DIR *d;
    struct dirent *dir;

    d = opendir(".");
    if (d) {
        filesList = (char **)malloc(size);
        while ((dir = readdir(d)) != NULL) {
            if (strstr(dir->d_name, ".jpeg")) {
                printf("%s\n", dir->d_name);
                filesList[numFiles] = (char *)malloc(256);
                filesList[numFiles++] = dir->d_name;
                size += 256;
                filesList = realloc(filesList, size);
            }
        }
        closedir(d);
    }
    *nof = numFiles;
    return filesList;
}

int main(int argc, char *argv[]) {
    unsigned char *buffer;
    char **filesList;
    int numberOfFiles;
    int width;
    int height;
    int pixel_size;
    int i;

    filesList = readDir(&numberOfFiles);

    for (i = 0; i < numberOfFiles; ++i) {
        printf("file: %s\n", filesList[i]); // <-- Here prints nothing in the second round

        buffer = readImage(filesList[i],
                           &width,
                           &height,
                           &pixel_size);
    }
    //free(temp);
    free(filesList);

    return EXIT_SUCCESS;
}

检查一下:

 jpeg_create_decompress(&cinfo); // <-- Exactly at this point, inputPath's content is erased ...
 // After this point, All filenames are erased

如果要运行代码,请下载库jpeglib 8c 然后,将文件夹的路径导出到PATH&amp; C_INCLUDE_PATH 然后,编译:

gcc file.c -ljpeg

1 个答案:

答案 0 :(得分:1)

目录枚举功能不正确:

  • 您为目录条目分配内存,但不是将字符串复制到该目录条目中,而是覆盖刚刚使用dir->d_name分配的指针,其内容可能会被进一步的readdir调用所破坏。< / LI>
  • 您的分配方案不精确,对于很长的文件名都会失败。

以下是更正后的版本:

char **readDir(int *nof) {
    char **filesList = NULL;
    int numFiles = 0;
    DIR *d;
    struct dirent *dir;

    d = opendir(".");
    if (d) {
        while ((dir = readdir(d)) != NULL) {
            if (strstr(dir->d_name, ".jpeg")) {
                printf("%s\n", dir->d_name);
                filesList = realloc(filesList, (numFiles + 1) * sizeof(char*));
                filesList[numFiles++] = strdup(dir->d_name);
            }
        }
        closedir(d);
    }
    *nof = numFiles;
    return filesList;
}

请注意,readDir()应将路径作为参数,strstr不是匹配fie扩展名的精确方法:list.jpeg.txt将被错误地包含在列表中。