【问题标题】:Pointer Content was deleted after function call, why? [closed]函数调用后指针内容被删除,为什么? [关闭]
【发布时间】:2016-02-08 00:04:00
【问题描述】:

我一直试图弄清楚我的代码发生了什么,但没有运气。我定义了一个指针: 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

【问题讨论】:

  • TL;博士。并格式化和缩进 minimal reproducible example!
  • 我尝试创建尽可能少的示例,但我无法重新生成错误。所以我通过一些初始化发布了我的整个方法。希望大家理解。
  • 'filesList[numFiles++] = dir->d_name;' - 你不应该复制那个 char 数组,而不仅仅是分配指针吗?
  • 另外,这个 'size += 256;'看起来不对。如果有什么你应该通过 sizeof(char*) 增加大小,不是吗?由于大小从 256 开始,所以没有理由增加它,直到所有 256 字节都充满指针。
  • C 不支持方法,什么意思?也不要将malloc 和朋友的结果投射到 C 中。

标签: c pointers memory


【解决方案1】:

目录枚举函数不正确:

  • 您为目录条目分配内存,但不是将字符串复制到其中,而是用dir-&gt;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 不是匹配文件扩展名的精确方式:list.jpeg.txt 将被错误地包含在列表中。

【讨论】:

  • 看起来更像,是的。
  • Thhhhhhaaaaannnnnxxxxx 这对我很有帮助。你是天才!
猜你喜欢
  • 2018-01-25
  • 2012-10-23
  • 2021-04-04
  • 2015-02-04
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
相关资源
最近更新 更多