段错误(核心已转储)和zlib

3

我很新于Linux的使用和C语言的编程。我一直试图创建一个简单压缩字符串的程序,但是当我尝试运行编译后的文件时,总是得到“Segmentation fault”的错误。 我使用以下命令编译:

gcc 2.c -o test.o -lz

我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include <assert.h>
int main ()
{
char *istream = malloc(10), *ostream = malloc(120);
istream = "istream";
int res = compress(ostream, (uLongf *)strlen(ostream), istream,(ulong)strlen(istream));
return 0;
}

有人能够解释一下为什么会出现这个错误,以及我应该如何改进我的代码吗?


为什么要加上 C++ 标签? - Sourav Ghosh
3个回答

4

这一行似乎是主要问题:

(uLongf*)strlen(ostream)

您正在将一个size_t值解释为缓冲区的指针。您应该传递一个包含输出缓冲区长度的unsigned long地址。请再次查看compress的文档。
另外,您还不理解C字符串的工作原理。当使用char* lvalue进行赋值操作时,仅会复制地址而不是字符串的内容。建议您像这样声明缓冲区:
const char *istream = "istream";
char ostream[120];

我认为你的程序应该大致如下:

我认为你的程序应该大致如下:

int main(void)
{
    const char *istream = "istream";
    char ostream[120];
    uLongf destLen = sizeof(ostream);
    int res = compress((Bytef*)ostream, &destLen, (Bytef*)istream, strlen(istream));
    return 0;
}

请注意,我写的代码是假定您正在使用C编译器,并因此使用了 int main(void)

该参数将是函数返回后压缩输出的实际大小,因此它是一个“输出”参数。 - Some programmer dude
1
@JoachimPileborg 它既是输入又是输出。我已经更正了我的答案。 - David Heffernan

2

首先,您需要使istream指向您分配的内存:

char *istream = malloc(10)

然后你将它指向一个字面量字符串(因此是常量且只读):

istream = "istream";

您需要将字符串文字复制到分配的内存中,否则您将不再拥有您分配的原始指针,并且会出现内存泄漏。您也无法释放该指针,因为istream指向的是您没有使用malloc分配的东西。
至于崩溃,请参见David Heffernan的答案。
顺便说一下,您的代码中没有C++,只有纯粹的C。

1

更改:

istream = "istream"

strcpy(istream,"istream");

此外,您期望strlen(ostream)返回什么?120吗? strlen返回输入字符串中第一个0字符的索引。
在您的情况下,由ostream指向的内存内容是未知的(即“垃圾”)。 strlen将扫描该内存,直到遇到0字符,但可能会超出120字节的内存空间并导致内存访问违规。
如果这是您的意图,请将strlen(ostream)更改为120。

尝试了这个和sprintf(istream, "istream"),仍然出现分段错误。 - FalconD
假设当您调用“compress”时发生了段错误异常,为什么不将此函数作为问题的一部分发布呢? - barak manos
等一下!调用 strlen(ostream) 是异常的原因。你期望它返回什么值?120吗?strlen 返回输入字符串中第一个0字符的索引。 - barak manos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接