缓冲区溢出 - 退出函数后未从堆栈中删除Char数组

时间:2014-12-25 12:58:02

标签: c string strcat

我正在尝试将几个字符串连接到缓冲区。但是,如果我反复调用该函数,我的缓冲区大小将继续增长。

void print_message(char *str) {
    char message[8196];
    sender *m = senderlist;
    while(m) {
        /* note: stricmp() is a case-insensitive version of strcmp() */
        if(stricmp(m->sender,str)==0) {
            strcat(message,m->sender);
            strcat(message,", ");
        }
        m = m->next;
    }
    printf("strlen: %i",strlen(message));
    printf("Message: %s\n",message);
    return;
}

消息的大小将持续增长,直到长度为3799.

示例:

  • 第一。 call:strlen = 211
  • 第二个电话:strlen = 514
  • 第3次电话:strlen = 844
  • ...
  • nth call:strlen = 3799
  • nth +1电话:strlen = 3799
  • nth +2 call:strlen = 3799

我的理解是,在退出函数时会自动释放像char []这样的静态分配变量,而且我不会在堆上动态分配任何东西。

为什么突然停止以3799字节增长?谢谢你的任何指示。

3 个答案:

答案 0 :(得分:3)

在缓冲区定义

之后再添加一条语句
char message[8196];
message[0] = '\0';

或者在定义缓冲区时初始化

char message[8196] = { '\0' };

char message[8196] = "";

完全等同于之前的初始化。

您的代码存在的问题是,如果您未明确指定初始化,则编译器不会初始化缓冲区。因此,数组消息包含一些垃圾,但函数strcat首先搜索缓冲区中的终止零,以附加新字符串。所以你的程序有不确定的行为。

答案 1 :(得分:2)

您所看到的是发件人名单的增长或邮件中可能存在的垃圾。幸运的是不超过8196。 消息数组必须以空字符串开头。目前做strcat会增加垃圾。

char message[8196];
sender *m = senderlist;
int len = 0;
*message = '\0';
while(m) {
    /* note: stricmp() is a case-insensitive version of strcmp() */
    if(stricmp(m->sender,str)==0) {
        int sender_len = strlen(m->sender);
        if (len + sender_len + 2 + 1 < sizeof(message)) {
            strcpy(message + len, m->sender);
            len += sender_len;
            strcpy(message + len, ", ");
            len += 2;
        } else {
            // Maybe appending "..." instead (+ 3 + 1 < ...).
            break;
        }
    }
    m = m->next;
}
printf("strlen: %i",strlen(message));
printf("Message: %s\n",message);

答案 2 :(得分:1)

&#34;解除分配&#34;与擦除数据不同;实际上,出于性能原因,C通常会将数据丢失。