首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分割故障strcat

分割故障strcat
EN

Stack Overflow用户
提问于 2022-10-13 01:06:05
回答 2查看 96关注 0票数 0

当读取导致分段错误的SSL响应时,我遇到了问题。我将响应读入缓冲区,然后将其附加到一个错误的字符串中,内存将其重置为0,直到响应被完全读取,但是当我在多线程程序中尝试时,在一些操作之后,它会给我分段错误。当我删除strcat时,即使我运行了几个小时,它也不会给我分段错误。

示例:

代码语言:javascript
复制
char* response = malloc(10000);
char buffer[10000] = { 0 };

while(SSL_read(ssl,buf,sizeof(buffer)) > 0){
    strcat(response,buffer);
    memset(buffer,0,sizeof(buffer));
}

错误

代码语言:javascript
复制
free(): invalid next size (normal)
malloc_consolidate(): invalid chunk

我确保了释放SSL和CTX以及关闭套接字,并释放了错误的字符串。

EN

回答 2

Stack Overflow用户

发布于 2022-10-13 04:46:45

您的代码有几个问题:

  1. 您不是在处理C字符串,而是处理任意字节序列。SSL_read()读取字节,而不是C字符串,您不能将它们视为字符串。您所阅读的内容不能被假定为NUL终止(\0),因此您不应该使用strcatstrlen或其他对字符串进行操作的类似函数。为了确保有一个终止符,对整个缓冲区进行零化没有什么意义,因为终止符可以很好地在数据中间找到。

  1. 您正在循环中连续地将数据读取到固定大小的缓冲区中。您的代码将很容易使目标缓冲区(response)溢出。

  1. 不是一个错误,但实际上并不需要一个中间缓冲区。当您可以直接读取到SSL_read()时,您将不必要地复制两次(一次用strcat,一次用strcat)。在此基础上,memset()为了清除buffer的内容,还增加了第三次扫描数据,使数据速度更慢。

同样,

  1. 不是一个错误,但是SSL_read()返回int并使用它返回读取大小。您并没有真正使用它,但是您应该使用它,因为您需要跟踪缓冲区上还剩下多少空间。不过,您最好使用size_t来避免不必要的签名数学问题和可能的溢出问题。您可以为此使用SSL_read_ex() .

下面是一段代码片段,它以更健壮的方式实现了您想要的结果:

代码语言:javascript
复制
#define CHUNK_SIZE 10000

unsigned char *response = NULL;
size_t size = 0;
size_t space_left = 0;
size_t total_read = 0;
size_t n;

while (1) {
    // Allocate more memory if needed.
    if (space_left < CHUNK_SIZE) {
        unsigned char *tmp = realloc(response, size + CHUNK_SIZE);
        if (!tmp) {
            // Handle realloc error
            break;
        }

        response = tmp;
        size += CHUNK_SIZE;
        space_left += CHUNK_SIZE;
    }

    if (SSL_read_ex(ssl, response + total_read, space_left, &n)) {
        total_read += n;
        space_left -= n;
    } else {
        // Handle error
        break;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2022-10-13 01:10:35

您从未初始化过response()strcat()的参数必须是以空结尾的字符串。

在调用SSL_read()时,还应该从缓冲区的大小中减去1,以确保始终存在空终止符的空间。

代码语言:javascript
复制
char* response = malloc(10000);
response[0] = '\0';
char buffer[10000] = { 0 };

while(SSL_read(ssl,buf,sizeof(buffer)-1) > 0){
    strcat(response,buffer);
    memset(buffer,0,sizeof(buffer));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74049447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档