【问题标题】:Can't declare two character pointers [duplicate]不能声明两个字符指针[重复]
【发布时间】:2012-10-27 12:32:33
【问题描述】:

可能重复:
why does c allow initialization of string without declaration?

我正在尝试这个相当简单的代码:

#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);

printf("%s",name);
}    

但由于某种原因,在我输入名称并按 Enter 后,程序挂起并给出消息,如 程序已停止工作。 但是,当我删除第二个字符指针声明时,是char *surname;,它按预期工作。这里有什么问题?

【问题讨论】:

    标签: c string pointers


    【解决方案1】:

    您没有为指针分配内存,因此scanf 访问任意未指定的内存,这是未定义的行为。

    您需要将指向足够大内存块的指针传递给scanf,要么声明

    char s1[100], s2[100];
    

    (如果 100 足够大),或malloc 内存

    char *s1 = malloc(100);
    char *s2 = malloc(100);
    if (!s1 || !s2) {
        // malloc failure
        exit(EXIT_FAILURE);
    }
    

    【讨论】:

      【解决方案2】:

      您正在写入未分配的内存。那是undefined behavior

      你可以在这里做两件事:

      1. 在编译时将您的字符数组声明为具有固定大小,如下所示:char name[100];(这意味着您无法在运行时更改它们的大小)
      2. 使用malloc()calloc() 中的stdlib.h 函数为char *name 分配空间

      在任何情况下,您绝对必须确保您只允许用户输入您分配的字节数,否则可能会发生坏事!

      如果您未能定义所述界限,可以在此处找到一个关于邪恶的人可以(并且将会;)做什么的小型研究:http://www.cultdeadcow.com/cDc_files/cDc-351/

      【讨论】:

      • 我不明白。那么,如果删除第二个声明,为什么它会起作用?
      • 正如我所说..“未定义的行为”您正在将“某处”写入非结构化内存中..任何事情都可能发生,并且会发生什么取决于编译器和/或平台。很可能内核意识到你非法覆盖了你在第一个之后声明的指针(这使得你很可能在第二个字符处写入它)并阻止你这样做。
      • @Cupidvogel UB 并不意味着程序崩溃,它意味着程序可以崩溃。
      • @GungFoo 另外,请将基于堆栈的(自动)数组选项添加到您的答案中。
      • @H2CO3 我做了你要求的编辑+添加了一些有趣的东西:)
      【解决方案3】:

      因为你没有为它分配内存,而你放入其中的字符串搞砸了程序的代码。尝试使用sscanfgetline

      #include <stdio.h>
      
      int main()
      {
        int nbytes = 100;
        char *my_string;
        int int1, int2, int3;
        int args_assigned;
      
        args_assigned = 0;
      
        while (args_assigned != 3)
          {
            puts ("Please enter three integers separated by whitespace.");
            my_string = (char *) malloc (nbytes + 1);
            getline (&my_string, &nbytes, stdin);
            args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
            if (args_assigned != 3)
          puts ("\nInput invalid!");
          }
      
        printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);
      
        return 0;
      }
      

      看看这个:

      Reading in a variable length string user input in C

      还有这个:

      http://en.wikipedia.org/wiki/Buffer_overflow

      【讨论】:

        【解决方案4】:

        你声明了一个指针,但没有给它一个有效的内存地址,它指向一个随机的地址。您不能使用此指针读取或写入。指针应该这样使用:

        char s1[100],s2[100];
        char * name=s1;
        char * surname=s2;
        

        【讨论】:

        • 为什么是那些无关的指针?只需将s1s2 传递给scanf()
        • 谢谢。另一个问题,指针,无论它们指向什么,它们本身实际上都是存储地址的整数,对吧?所以*p = "foo" 会将一些整数值放入p,这将是程序存储foo 的地址,对吧?那我们怎么可以给p分配字符串,比如p = "barbar"
        • 字符 *p; *p ="foo" 是错误的。 p="foo" 是对的。因为在 C 中,字符串是字符指针。
        • (1)是的,指针实际上是整数,更准确地说,是特殊整数,其值为内存地址。在某些 IDE 中,您可以将整数分配给指针 char * p =10; 并且我们可以为指针添加一些值:p+=20; 当然,当您向指针添加数字 N 时,指针的值将增加而不是 N但是 N*sizeof (元素)。 (2)您的代码:char *p; *p ="foo"; 错误。 p="foo" 是对的。因为在 C 中,字符串是 char 指针。指针应该分配给指针。
        • @H2CO3:只需使用s1s2 即可。但是问题的作者想知道如何使用指针。所以我必须使用指针作为演示。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 2019-03-01
        • 2012-05-09
        • 1970-01-01
        相关资源
        最近更新 更多