【问题标题】:C. Passing pointers to be modified causing segmentation faultsC. 传递要修改的指针导致分段错误
【发布时间】:2016-05-03 22:35:34
【问题描述】:

我正在用 C 语言为一个类制作一个十进制到二进制的转换器。我想将一个 char 数组传递给我的函数以及作为 int 的小数。 即 void DtoB(int decimal, char *array); DtoB 将进行数学运算并将数组修改为二进制值。理想情况下,通过给它 int 值。 Main() 只会 scanf(decimal)、DtoB(decimal,array) 和 printf(array)。

这就是我所拥有的。这只是返回一个分段错误

1 #include <stdio.h>
2 #include <math.h>
3
4 void DecToBin(unsigned int, char *binary);
5
6 int main()
7 {
8         unsigned int dec;
9         char *binary[];
10         while(1) {
11                 scanf("%d", &dec);
12                 DecToBin(dec,*binary);
13                 printf("In binary is ");
14                 printf("%s\n",binary);
15         }
16 }
17 void DecToBin(unsigned int dec, char *binary)
18 {
19         int counter=0;
20         while(dec) {
21                 binary[counter]=dec%2;
22                 dec/=2;
23                 counter++;
24         }
25 }

我希望这样做,因为这似乎是能够处理 32 位整数的最佳方式,同时将数组保持在最小大小。 对不起,如果我杀死了格式化。任何帮助表示赞赏。

【问题讨论】:

  • char *binary[33]; 声明了一个 array-of-pointers——没有一个被分配。 DecToBin(dec,*binary)DecToBin(dec, binary[0]) 相同。
  • 正如目前所写,char *binary[]; 不会编译;您不能在没有非零大小的函数体中定义数组(GCC 可能允许零大小,但这是编译器扩展)。您实际上想要char binary[33];,然后将binary(而不是*binary))传递给您的函数。
  • 在编写/发布代码时,不要使用制表符进行缩进。因为每个字处理器/编辑器的制表位/制表宽度设置不同建议为每个缩进级别使用 4 个空格,因为它足够宽,即使使用可变宽度字体也可以看到,并且仍然允许在页面上进行多级缩进
  • 这一行:DecToBin(dec,*binary); 正在取消引用数组/指针binary[] 建议:DecToBin(dec,binary);。这是因为在 C 中,数组名称(在大多数情况下)降级为数组第一个字节的地址。
  • 一般来说,代码应该总是检查来自scanf()的返回值(不是参数值),以确保操作成功。在这种情况下,返回值应该是 1。

标签: c pointers segmentation-fault


【解决方案1】:

合并所有的cmets,合并错误检查等,贴出来的代码变成:

#include <stdio.h>
#include <stdlib.h>  // exit(), EXIT_FAILURE
#include <string.h>  // memset()


// prototypes
void DecToBin(unsigned int, char *binary);

int main()
{
        unsigned int dec;
        char binary[sizeof(int)*8 +1];


        while(1)
        {
                if( 1 != scanf("%u", &dec) )
                { // then scanf failed
                    perror( "scanf for decimal value failed" );
                    exit( EXIT_FAILURE );
                }

                // implied else, scanf successful

                DecToBin(dec, binary);
                printf("In binary is ");
                printf("%s\n",binary);
        }
}


void DecToBin(unsigned int dec, char *binary)
{
        size_t counter= sizeof(int)*8;

        memset( binary, ' ', counter );
        binary[ counter ] = '\0'; // terminate string
        counter--;

        // do...while allows for dec being 0
        do
        {
                binary[counter]= (char)((dec%2)+ 0x30);
                dec /= 2;
                counter--;
        }  while(dec);
}

它仍然存在留给用户空白屏幕和闪烁光标的缺点。 IE。代码应该通过请求输入值来提示用户。

【讨论】:

  • 您可以使用CHAR_BIT 代替8(自我记录稍微多一点)
  • 其实是在等待输入,只要提供输入命中返回,也可以在while(1) {}开头加上一些像printf("请提供输入")这样的想法,它会是有用知道它正在等待输入
【解决方案2】:
char *binary[33]

二进制是指针数组。所以其中的每个元素都是一个指针。

分段错误是因为您没有初始化数组并尝试使用它。

您正在取消引用一个未指向任何有效内存位置的指针。

在使用数组成员之前需要为它们分配内存

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多