[C语言]一个带有可变长度字符串参数的函数在接收长字符串时报错

目标函数,是接受一连串的字符串,可能非常的长,然后把每个字符转化成对应的16进制(字符串格式)
但是如下会报错。但假如我缩短param的字符长度为比如”JJJJJJJJJJ“,就不会报错了。
由于认为char *character为可变长度且用了malloc不理解为何会过长。求教,非常感谢!

char *convert_to_16(char *characters, int n){

    // int c_length = strlen(characters);
    char sub_buffer[3];
    char code[3];
    char buf[3];
    char *buffer = (char*)malloc(sizeof(characters) * 2);
    for(int i=0; i < n; i++){
        strncpy(code, characters+i, 1);
        code[1+i]=0;
        sprintf(sub_buffer, "%x", *code);
        sprintf(buf, "%s", sub_buffer);
        strncat(buffer, buf, 2);
    } 
    return buffer;
}

int main(){
    char param[] = "JjjjjdddddddddJJJJJJJJJJJJJJJJJdddjjj";
    printf("%s\n", param);
    int length = strlen(param);
    printf("%s\n", convert_to_16(param, length));
}




问题已经解决,去掉code[1+i]就无问题了。但是原理和内存方面的控制貌似会有问题,若有见解欢迎赐教,谢谢!

阅读 4.4k
3 个回答
char *convert_to_16(char *characters, int n){

    // int c_length = strlen(characters);
    char sub_buffer[3];
    char code[3];//改为2
    char buf[3];
    char *buffer = (char*)malloc(sizeof(characters) * 2);//长度错误, 改为2n+1
    //增加下面一行,malloc并不会将分配空间初始化为0
    buffer[0]='\0';
    for(int i=0; i < n; i++){
        strncpy(code, characters+i, 1);
        code[1+i]=0;//此处strlen(code)应为1,改为code[1]='\0'
        //下面两个重复可以省略一个
        sprintf(sub_buffer, "%x", *code);
        sprintf(buf, "%s", sub_buffer);
        strncat(buffer, buf, 2);
    }
    return buffer;
}

int main(){
    char param[] = "JjjjjdddddddddJJJJJJJJJJJJJJJJJdddjjj";
    printf("%s\n", param);
    int length = strlen(param);
    printf("%s\n", convert_to_16(param, length));
}

char *buffer = (char*)malloc(sizeof(characters) * 2);
改为
char *buffer = (char*)malloc(strlen(characters) * 2);
经典问题了,你这里得到的是指针大小
传进去的n怎么不直接用呢,第一句为何注释掉了。。。

上面 @后沟书库 已经指出了全部的问题。这里,我补充一点,将 buffer 的第一个元素赋为 \0 对于循环中的 strncat 那句是非常重要的。因为 strncat 函数会将它的第 2 个参数(字符串)添加到第 1 个参数(字符串)的尾部,而这个尾部是靠 \0 进行判断的。所以,如果 buffer 的第一个元素不是 \0,这个程序其实就是完全错的,即使它可能会输出正确的结果。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *convert_to_16(char *s)
{
        char a[2], b[3];
        char *buffer = malloc(2 * strlen(s) + 1);
        buffer[0] = '\0'; 
        for( ; *s != '\0'; s++) {
                strncpy(a, s, 1);
                a[1] = '\0';
                sprintf(b, "%x", *a);
                strncat(buffer, b, 2);
        }
        return buffer;
}

int main(void)
{
        char param[] = "JjjjjdddddddddJJJJJJJJJJJJJJJJJdddjjj";
        printf("%s\n", param);
        
        char *result = convert_to_16(param);
        printf("%s\n", result);
        free(result);
        
        return 0;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进