【问题标题】:Stack smashing in C on function return函数返回时 C 中的堆栈粉碎
【发布时间】:2018-03-18 10:50:23
【问题描述】:

我有一个小程序,可以将 12 小时制转换为 24 小时制。

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>

int get_tokens(char* buf, char *fields[], char *sep){

    char* ptr= (char*)malloc((10*sizeof(char))+1);
        strncpy(ptr, buf, 10);
        *(ptr+10)='\0';
    int num_f=0;

    while((fields[num_f] = strtok(ptr,sep)) != NULL ){
        ptr = NULL;
        num_f++;
    }
    return num_f;
}


char* timeConversion(char* s) {
    char *fields[3];
    int num_f=0;
    char *ptr = (char*) malloc(100*sizeof(char));
    int hour=0;

    get_tokens(s, fields, ":");
    if(strstr(s,"PM")){
        hour=atoi(fields[0])+12;
    }
    else{
      hour=atoi(fields[0]);
    } 

    snprintf(ptr, 9, "%d:%s:%s" ,hour,fields[1],fields[2]);
    return ptr;
}

int main() {
    char* s = (char *)malloc(100 * sizeof(char));
    scanf("%s", s);
    char* result = timeConversion(s);
    printf("%s\n", result);
    return 0;
}

我在 timeConversion 函数返回后立即看到“堆栈粉碎”。 我知道代码的逻辑有效,但无法弄清楚堆栈粉碎。

【问题讨论】:

  • scanf("%s", s); 至少有 3 个问题。
  • 不要投射malloc(),乘以sizeof(char)是没有意义的,因为它是1
  • 不要使用strncpy。这是可憎的。
  • @CIsForCookies 不,&amp;s 是错误的。 1) 确实是潜在的缓冲区溢出(没有长度限制)。 2) 不检查返回值以确保scanf 成功读取字符串。 3) 完全使用scanf 进行用户输入。 scanf %s 特别不是基于行的;它将跳过任何初始空白,然后读取一系列非空白字符,这对于程序员(该行的其余部分(包括最后的换行符)保留在输入缓冲区中)和用户(如果您只是按 Enter 键,程序似乎会挂起)。
  • @Zebrafish 如果您确实需要strncpy 的功能,可以使用memcpymemset 的组合。但是,如果您只想执行有界字符串复制(这不是 strncpy 所做的,尽管它的名称),最简单的方法是 snprintf

标签: c pointers char stack-smash


【解决方案1】:

函数get_tokens 使用 3 个指针写入堆栈分配的缓冲区,而不检查缓冲区容量限制。 fields[num_f] = strtok 可能会导致堆栈缓冲区溢出。同时fields 项目可以在未初始化的情况下使用。

还有一个内存泄漏,因为您从未free 分配内存。

【讨论】:

  • 就导致堆栈缓冲区溢出的字段 [num_f] = strtok 而言,strtok 必须在该循环中运行 4 次,对吗?因为他制作了一个 char 字段数组[3];
  • @Zebrafish 是的,第 4 次循环会出现超限。
  • 感谢 VTT。这确实是问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多