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

标签 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 & C_INCLUDE_PATH 然后,编译:

gcc file.c -ljpeg

最佳答案

目录枚举函数不正确:

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

这是更正后的版本:

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 将被错误地包含在列表中。

关于c - 函数调用后指针内容被删除,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35260761/

相关文章:

c - Golang C 绑定(bind)类型设计

c - 在C中访问数组的连续条目

java - 使用Parse.com指针查询两个类的数据,指针值异常

c - 如何减轻转置数组访问顺序对性能的影响?

c++ - c、共享库中的c++内存

c++ - 堆分配的成员引用是一个糟糕的主意吗?为什么?

c - 有没有办法在不读取 linux 上的 proc/sys 文件的情况下获取电池信息(状态、插入等)?

c++ - 了解 gettimeofday 系统调用

c - 如何在 pcre2_substitute 中设置输出大小

C - 传递分配的指针并在单独的函数中使用 realloc