【问题标题】:free(ptr) crashes sometimes, pointer is always valid [closed]free(ptr)有时会崩溃,指针始终有效[关闭]
【发布时间】:2014-11-26 11:31:22
【问题描述】:

我正在尝试创建一些动态分配的字节流,并在其他地方执行它们的副本。我的代码是这样的(之前我没有从电脑上输入 :)):

    void construct_cypherstreams(uint8_t * stream, int key_length, int stream_length, uint8_t ** encr_streams, int * bytes_in_stream) {
        // chyperstream = the stream formed of every ith byte
        uint8_t * cypherstream;
        int length;
        length = stream_length / key_length + 1;
        // each byte of the key can have values
        // between 0 and 256
        int i = 0;
        int num_added = 0;
        for (int k = 0; k < key_length; k++) {
            printf("\n%s %d\n", "iteration", k);
            i = k; num_added = 0;
            cypherstream = (uint8_t *)malloc(length * sizeof (char));
            if (cypherstream == NULL) {
                printf("%s\n", "could not allocate");
                exit(1);
            }
            else {
                printf("%s\n", "succesfully allocated");
            }
            while (i < stream_length) {
                // construct cypherstream
                cypherstream[num_added] = stream[i];
                num_added++;
                i += key_length;
            }
            printf("\n%s\n", "created cypherstream:");
            for (int m = 0; m < num_added; m++) {
                printf("%X", cypherstream[m]);
            }
            printf("\n");
            printf("%s\n", "making deep copy...");
            encr_streams[k] = (uint8_t *)malloc(num_added * sizeof(char));
            // perform deep copy of characters
            for (int n = 0; n < num_added; n++) {
                encr_streams[k][n] = cypherstream[n];
            }
            printf("%s\n", "done making deep copy");
            free(cypherstream);
            printf("%s\n", "succesfully freed");
            printf("%s %d\n", "position:", k);
            printf("%s %d\n", "num_added:", num_added);
            bytes_in_stream[k] = num_added;
            printf("%s\n", "iteration ended");
        }
    }

我这样称呼它:

    uint8_t ** encr_streams;
    int  * bytes_in_stream;
    encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);
    bytes_in_stream = (int *)malloc(key_length * sizeof *bytes_in_stream);
    construct_cypherstreams(stream, key_length, stream_length, encr_streams, bytes_in_stream);

现在我的程序有时会运行,有时会崩溃。 我暂时被困在这里,我真的可以使用一些帮助。 编译器:msvc 谢谢

【问题讨论】:

  • 如果我不能“争论”关于转换指针的问题,我可以指出您的printf() 用法非常奇怪吗?你可以只做printf("making deep copy...\n");puts("making deep copy..."); 而不是那种陌生感。
  • 确保您没有对//do a lot of stuff 中的stream 指针进行stream++ 或任何其他算术运算。
  • 您没有显示相关代码,因此无法为您提供帮助。最可能的错误是您覆盖了stream 或其他一些动态分配的内存。进行此类覆盖可能会损坏堆系统的内部簿记数据,从而导致 free() 在依赖该数据正确时崩溃。
  • 指针有效是不够的。 free 的参数必须是调用 malloc/calloc/realloc 返回的确切值。
  • 没有算术,我只使用索引。它也是 malloc 返回的相同值。没有 realloc 或 calloc

标签: c segmentation-fault free


【解决方案1】:
encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);

只是看起来不对。我觉得应该是

encr_streams = malloc(key_length * sizeof *encr_streams);

因为您似乎打算分配一个指向uint8_t 的指针数组。然后你可能还需要用一些东西来初始化那个数组的元素。

【讨论】:

  • 我其实想分配一个指针数组。
  • 你是对的。在按照 Ben Williams 的建议更改代码后,我实际上使它工作了,但我想我有不止一个问题。我意识到我想要一个指针数组,但我正在为chars 分配空间。我想我很幸运它成功了
【解决方案2】:

这是堆损坏的情况,因为您试图覆盖一些动态分配的内存。

【讨论】:

  • 你能解释一下你的答案吗?
【解决方案3】:

如果您在 Linux 上编程,请在 valgrind 内存调试器下运行您的代码:

对于 Windows...您可能想尝试 MS AppVerifier,尽管我已经多年没有使用它并且几乎忘记了它的所有内容 :-(

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    相关资源
    最近更新 更多