简体   繁体   English

指向char指针字符串的整数数组

[英]integer array to char pointer string

I'm trying to convert int array to char pointer string (array values converted to hex).I'm using codeblocks editor. 我正在尝试将int数组转换为char指针字符串(将数组值转换为十六进制)。我正在使用代码块编辑器。
so, 所以,

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

should be converted to 应该转换为

                            char *str =  "1e280fcd";

I have written the following program to do so: 为此,我编写了以下程序:

#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;
}

This program's output is either 该程序的输出为

  • segmentation fault or 分割错误或
  • A string with garbage value in the initial locations 初始位置具有垃圾值的字符串

在此处输入图片说明

在此处输入图片说明

I've run the same program on different online compilers. 我已经在不同的在线编译器上运行了相同的程序。 They all give the correct string as output.Is the editor i'm using an issue or my memory management methods? 它们都给出正确的字符串作为输出。我是在使用编辑器还是问题或内存管理方法?

In

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

the sprintf write 3 characters including the final null character, while you allocated only 2 sprintf会写3个字符,包括最后一个空字符,而您只分配了2个

In

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

the allocate length is not the right one because the size_of do not return what you expect, must be 分配长度不正确,因为size_of不返回您期望的值,必须是

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

but of course that supposes prev_str is also a correct string at the beginning, and this is not the case 但是当然prev_strprev_str也是正确的字符串,事实并非如此

These two malloc will produce memory leaks because there are not free (nor used) 这两个malloc将产生内存泄漏,因为没有空闲空间(也不使用)

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

Why do you not use realloc to increase the size of prev_str ? 为什么不使用realloc增加prev_str的大小?

Note the final needed size is easy to know : sizeof(arr)/sizeof(arr[0]) * 2 + 1 if numbers a limited to 255 (2 digits in hexa) 注意最终所需的大小很容易知道: sizeof(arr)/sizeof(arr[0]) * 2 + 1如果数字限制为255(六位数为2位)

A proposal (without supposing all numbers < 256) : 提案(不假设所有数字<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;
}

Compilation and xecution : 编译和执行:

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

Execution under valgrind 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)

That was a lot of dynamic memory allocation for a simple task. 一个简单的任务需要大量的动态内存分配。 If the array and string will remain "small" then use the stack to your advantage: 如果数组和字符串将保持“小”状态,则可以使用堆栈:

#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;
}

But if you truly need a dynamic string, ie, char *str just modified char str[2 * arr_length + 1]; 但是,如果您确实需要动态字符串,即char *str只需修改char str[2 * arr_length + 1]; to

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

and add free(str); 并添加free(str);

NB: All this assumes that you integer array values are less than 256. 注意:所有这些都假定您的整数数组值小于256。

the following proposed code: 以下建议的代码:

  1. eliminates the unneeded code logic 消除了不必要的代码逻辑
  2. eliminates the unneeded variables 消除不必要的变量
  3. eliminates the unneeded use of dynamic memory 消除了不必要的动态内存使用
  4. cleanly compiles 干净地编译
  5. does NOT seg fault 不分段故障
  6. performs the desired functionality 执行所需的功能
  7. note that strlen() returns a size_t , not a int 请注意, strlen()返回size_t ,而不是int
  8. note that sizeof() returns a size_t not a int 请注意, sizeof()返回的是size_t而不是int
  9. multiplies the length of the array arr[] by 2 to calculate the number of characters needed to display the converted array 将数组arr[]的长度乘以2以计算显示转换后的数组所需的字符数
  10. adds 1 to the calculated length to allow for the trailing NUL byte 将1加到所计算的长度以允许尾随NUL字节
  11. lists the variables in the necessary order so specific parameters are always available when needed 以必要的顺序列出变量,以便在需要时始终可以使用特定的参数

And now, the proposed code: 现在,建议的代码:

#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);
    }
}

A run of the proposed code results in: 运行建议的代码将导致:

1e
1e28
1e280f
1e280fcd

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM