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

时间:2022-09-06 19:59:05

I've been trying to figure out what's going on with my code, but no luck. I have defined a pointer: char ** filesList = readDir(); The pointer is pointing to an array of Strings. I was able to have all filenames in the current directory. That's not the issue.

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

When I pass filesList[i], for any i=0,..,n : readImage(filesList[i],...); the content of filesList is erased.. I don't know why.. Any help?!

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

My code:

#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;
}

Check this:

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

If you want to run the code, download the library jpeglib 8c then, export the folder's path to PATH & C_INCLUDE_PATH then, compile with:

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

gcc file.c -ljpeg

1 个解决方案

#1


1  

The directory enumeration function is incorrect:

目录枚举函数不正确:

  • You allocate memory for the directory entry, but then instead of copying the string into that, you overwrite the pointer you just allocated with dir->d_name, whose contents may get clobbered by further readdir calls.
  • 您为目录条目分配内存,但不是将字符串复制到该目录条目中,而是覆盖刚刚使用dir-> d_name分配的指针,其内容可能会被进一步的readdir调用破坏。

  • Your allocation scheme is imprecise and will fail for very long filenames.
  • 您的分配方案不精确,对于很长的文件名将失败。

Here is a corrected version:

这是一个更正版本:

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;
}

Note that readDir() should take the path as an argument, and strstr is not a precise way to match fie extensions: list.jpeg.txt will be mistakenly included in the list.

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

#1


1  

The directory enumeration function is incorrect:

目录枚举函数不正确:

  • You allocate memory for the directory entry, but then instead of copying the string into that, you overwrite the pointer you just allocated with dir->d_name, whose contents may get clobbered by further readdir calls.
  • 您为目录条目分配内存,但不是将字符串复制到该目录条目中,而是覆盖刚刚使用dir-> d_name分配的指针,其内容可能会被进一步的readdir调用破坏。

  • Your allocation scheme is imprecise and will fail for very long filenames.
  • 您的分配方案不精确,对于很长的文件名将失败。

Here is a corrected version:

这是一个更正版本:

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;
}

Note that readDir() should take the path as an argument, and strstr is not a precise way to match fie extensions: list.jpeg.txt will be mistakenly included in the list.

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