整数数组到char指针字符串

问题描述 投票:0回答:3

我正在尝试将int数组转换为char指针字符串(数组值转换为十六进制)。我正在使用codeblocks编辑器。 所以,

                           int arr[4] = {30, 40, 15, 205};

应转换为

                            char *str =  "1e280fcd";

我写了以下程序:

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

int main()
{
    char *cur_str, *prev_str;
    char *comp_str, *comp_str_copy;
    int arr[] = {30,40,15,205}, i, j, arr_length;
    arr_length = (sizeof(arr)/sizeof(arr[0]));
    prev_str = malloc(sizeof(0));
    cur_str = malloc(sizeof(0));
    comp_str = malloc(sizeof(0));
    for(i=0;i<arr_length;i++)
    {
        cur_str = malloc(2);
        sprintf(cur_str,"%02x",arr[i]);

        comp_str = malloc(sizeof(cur_str)+sizeof(prev_str));
        sprintf(comp_str,"%s%s",prev_str,cur_str);
        printf("%s\n",comp_str);

        free(prev_str);
        prev_str = malloc(sizeof(comp_str));
        sprintf(prev_str,"%s",comp_str);

        if(i==(arr_length-1)){
            comp_str_copy = malloc(sizeof(comp_str));
            sprintf(comp_str_copy,"%s",comp_str);
        }

        free(comp_str);
        free(cur_str);
    }
    printf("%s %d\n",comp_str_copy,strlen(comp_str_copy));
    return 0;
}

该程序的输出是

  • 分段错误或
  • 初始位置中具有垃圾值的字符串

enter image description here

enter image description here

我在不同的在线编译器上运行相同的程序。它们都给出正确的字符串作为输出。编辑器我是使用问题还是我的内存管理方法?

c memory-management malloc
3个回答
1
投票

    cur_str = malloc(2);
    sprintf(cur_str,"%02x",arr[i]);

sprintf写入3个字符,包括最后的空字符,而你只分配2个字符

comp_str = malloc(sizeof(cur_str)+sizeof(prev_str));

分配长度不是正确的,因为size_of不会返回你期望的,必须

comp_str = malloc(strlen(cur_str)+strlen(prev_str)+1);

但当然,假设prev_str在开始时也是一个正确的字符串,事实并非如此

这两个malloc会产生内存泄漏,因为没有free(也没有使用)

cur_str = malloc(sizeof(0));
comp_str = malloc(sizeof(0));

为什么不使用realloc来增加prev_str的大小?

注意最终所需的大小很容易知道:sizeof(arr)/sizeof(arr[0]) * 2 + 1如果数字限制为255(六位数为2位)

提案(不假设所有数字<256):

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

int main()
{
    int arr[] = {30,40,15,205};
    size_t arr_length = sizeof(arr)/sizeof(arr[0]);
    size_t i;
    size_t sz = 0;
    char * r = malloc(0);

    for (i=0; i!= arr_length; ++i)
    {
      char s[20];
      int l = sprintf(s, "%02x",arr[i]);

      r = realloc(r, sz + l + 1);
      strcpy(r + sz, s);
      sz += l;
    }
    printf("%s %d\n", r, sz);
    free(r);
    return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra a.c
pi@raspberrypi:/tmp $ ./a.out
1e280fcd 8

在valgrind下执行

pi@raspberrypi:/tmp $ valgrind ./a.out
==2985== Memcheck, a memory error detector
==2985== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2985== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2985== Command: ./a.out
==2985== 
1e280fcd 8
==2985== 
==2985== HEAP SUMMARY:
==2985==     in use at exit: 0 bytes in 0 blocks
==2985==   total heap usage: 6 allocs, 6 frees, 1,048 bytes allocated
==2985== 
==2985== All heap blocks were freed -- no leaks are possible
==2985== 
==2985== For counts of detected and suppressed errors, rerun with: -v
==2985== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

1
投票

对于一个简单的任务来说,这是很多动态内存分配。如果数组和字符串保持“小”,那么使用堆栈有利于您:

#include <assert.h>
#include <stdio.h>

int main() {
    int const arr[] = {30, 40, 15, 205};
    int const arr_length = sizeof(arr) / sizeof(arr[0]);
    char str[2 * arr_length + 1];
    int len = 0;
    for (int i = 0; i < arr_length; i++) {
        len += sprintf(&str[len], "%02x", arr[i]);
    }
    assert(len == 2 * arr_length);
    printf("%s %d\n", str, len);
    return 0;
}

但如果你真的需要一个动态字符串,即char *str刚刚修改了char str[2 * arr_length + 1];

char *str = malloc(2 * arr_length + 1);

并添加free(str);

注意:所有这些都假定您的整数数组值小于256。


1
投票

以下提议的代码:

  1. 消除了不需要的代码逻辑
  2. 消除了不需要的变量
  3. 消除了不必要的动态内存使用
  4. 干净利落地编译
  5. 不会出错
  6. 执行所需的功能
  7. 请注意,strlen()返回size_t,而不是int
  8. 请注意,sizeof()返回size_t而不是int
  9. 将数组arr[]的长度乘以2,以计算显示转换后的数组所需的字符数
  10. 将计算长度加1以允许尾随NUL字节
  11. 以必要的顺序列出变量,以便在需要时始终可以使用特定参数

现在,建议的代码:

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

int main( void )
{
    int arr[] = {30,40,15,205};
    char comp_str[ sizeof( arr )*2 +1 ] = {'\0'};  

    size_t arr_length = (sizeof(arr)/sizeof(arr[0]));

    for( size_t i=0; i<arr_length; i++ )
    {          
        sprintf( comp_str,"%s%02x", comp_str, arr[i] );
        printf("%s\n",comp_str);
    }
}

运行的建议代码导致:

1e
1e28
1e280f
1e280fcd
© www.soinside.com 2019 - 2024. All rights reserved.