我有一个名为num_to_binary
的函数,用于转换以数组形式存储的十进制数。该函数num_to_binary
的原型如下:
void num_to_binary(int *number_b, int size_of_number);
此处:
number_b
是指向存储我的号码的数组的指针。例如,如果我想将数字12345转换为二进制,那么我将在number_b
中存储12345,如下所示:
number_b[0] = 1
number_b[1] = 2
number_b[2] = 3
number_b[3] = 4
number_b[4] = 5
此外,size_of_number
是数字中的位数(或者是数组number_b
中的元素数)。因此,对于数字12345,size_of_number
的值为5。
以下是函数num_to_binary
:的完整声明
void num_to_binary(int *number_b, int size_of_number)
{
int *tmp_pointer = malloc(1 * sizeof(int));
int curr_size = 1;
int i = 0;
while(!is_zero(number_b,size_of_number))
{
if(i != 0)
{
curr_size += 1;
tmp_pointer = realloc(tmp_pointer, curr_size * sizeof(int));
}
if(number_b[size_of_number - 1] % 2 == 1)
{
tmp_pointer[i] = 1;
divide_by_2(number_b,size_of_number);
i = i + 1;
}
else
{
tmp_pointer[i] = 0;
divide_by_2(number_b,size_of_number);
i = i + 1;
}
}
int *fin_ans;
fin_ans = malloc(curr_size * sizeof(int));
for(int j = 0 ; j < curr_size; j++)
{
fin_ans[curr_size-1-j] = tmp_pointer[j];
}
}
在上述功能中:
tmp_pointer
:最初使用malloc()
为其分配一些内存,用于存储number_b
中存储的数字的二进制表示的反向
curr_size
:存储tmp_pointer
的当前大小。它最初设置为1。i
:用于跟踪while
循环。它也用于重新分配的目的,我稍后会对此进行解释。
is_zero(number_b, size_of_number)
:是一个函数,如果number_b
中存储的数字为0,则返回1
,否则返回1。
divide_by_2(number_b, size_of_number)
:将存储在number_b
中的数字除以2。它不会改变数组number_b
的大小。
fin_ans
:是一个整数指针。由于存储在数组tmp_pointer
中的二进制表示将与数字的实际二进制表示相反,因此fin_ans
将通过反转tmp_pointer
的内容来存储数字的正确二进制表示。
以下是该功能的工作原理:
- 首先,
tmp_pointer
被分配了一个等于大小为1int。因此,现在tmp_pointer
可以存储一个整数 - 现在我们进入
while
循环。循环将仅终止当存储在CCD_ 30中的数字等于0时 - 现在,我们检查
i
是否等于0。如果不等于零,则这意味着循环至少运行了一次,并且为了存储下一个二进制数字,我们调整内存大小分配给CCD_ 32以便其可以存储下一个比特 - 如果数字的最后一位是奇数,那么这意味着相应的二进制数字将为1,否则将为0。这个CCD_ 33和CCD_。它们也会增加
i
,并且还将该数字除以2 - 现在,我们脱离了循环。该倒二进制数了存储在CCD_ 36中以获得最终答案
- 为此,我们创建了一个名为
fin_ans
的新指针,并分配它是用于存储正确二进制文件的存储器数字的表示 - 最后一个
for
循环用于反转二进制表示并将正确的二进制表示存储在CCD_ 39中
问题:
该代码适用于123等小数字,但对于1234567891等大数字,它会给出分段错误。这可以通过尝试打印存储在fin_ans
中的数字来进行检查。
我尝试使用GDB调试器,并了解到Segmentation Fault的原因在于while
循环。我确信函数divide_by_2
和is_zero
不是Segmentation Fault的原因,因为我已经对它们进行了彻底的测试。
我还使用了DrMemory,这表明我正在尝试访问(读取或写入)尚未分配的内存位置。不幸的是,我不知道错误在哪里。
我怀疑realloc()
是Segmentation Fault的原因,但我不确定。
对于这么长的问题,我深表歉意,但是,我将非常感谢为我提供的任何有关此代码的帮助。
提前谢谢你帮我!
代码中存在多个问题:
- 您没有检查内存分配失败
- 您在离开该功能之前忘记释放
tmp_pointer
- 您分配了一个新的数组
fin_ans
来保留数组tmp_pointer
并执行反向操作,但您没有将此数组返回给调用者,也没有返回其大小的方法。您应该更改原型以返回此信息 - 如果数字为零,则转换后的数字可能会有1位初始化为0,但您使用的
malloc
不会初始化它分配的数组,因此tmp_pointer[0]
未初始化 - 您没有提供
is_zero()
和divide_by_two()
的代码。这些函数中的错误可能会导致分段故障,特别是如果循环没有达到零,并且在这个无限循环中内存最终耗尽
这是一个修改后的版本:
int *num_to_binary(int *number_b, int size_of_number, int *binary_size) {
int i, j, curr_size;
int *p, *newp;
curr_size = 1;
p = malloc(1 * sizeof(int));
if (p == NULL)
return NULL;
p[0] = 0;
for (i = 0; !is_zero(number_b, size_of_number); i++) {
if (i != 0) {
curr_size += 1;
newp = realloc(p, curr_size * sizeof(int));
if (newp == NULL) {
free(p);
return NULL;
}
p = newp;
}
p[i] = number_b[size_of_number - 1] % 2;
divide_by_2(number_b, size_of_number);
}
for (i = 0, j = curr_size; i < j; i++)
int digit = p[--j];
p[j] = p[i];
p[i] = digit;
}
*binary_size = curr_size;
return p;
}
不需要多个内存重新分配。结果内存缓冲区大小可以很容易地评估为十进制输入值的二进制对数。数字二进制表示的计算也可以简化:
//Transform binary array to actual number
int arr2int(int* pIntArray, unsigned int nSizeIn) {
if (!pIntArray || !nSizeIn)
return 0;
int nResult = 0;
for (unsigned int i = 0; i < nSizeIn; ++i)
nResult += pIntArray[i] * (int)pow(10, nSizeIn - i - 1);
return nResult;
}
int* int2bin(int* pIntArray, unsigned int nSizeIn, unsigned int* nSizeOut){
//0) Converting int array to the actual value
int nVal = arr2int(pIntArray, nSizeIn);
//1)Evaluating size of result array and allocating memory
if(!nVal)
*nSizeOut = 1;
else
*nSizeOut = (int)floor(log2(nVal)) + 1;
//2)Allocate and init memory
int* pResult = malloc(*nSizeOut);
memset(pResult, 0, *nSizeOut * sizeof(int));
//3) Evaluate binary representation
for (unsigned int i = 0; i < *nSizeOut; ++i){
int nBinDigit = (int)pow(2, i);
if (nBinDigit == (nVal & nBinDigit))
pResult[*nSizeOut - i - 1] = 1;
}
return pResult;
}
测试:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define _DC 9
int main()
{
int test[_DC];
for (int i = 0; i < _DC; ++i)
test[i] = i;
unsigned int nRes = 0;
int* pRes = int2bin(test, _DC, &nRes);
for (unsigned int i = 0; i < nRes; ++i)
printf("%d", pRes[i]);
free(pRes);
return 0;
}