【问题标题】:char[] vs char* in scanf C when writing memory [duplicate]写入内存时scanf C中的char [] vs char * [重复]
【发布时间】:2016-10-24 00:09:15
【问题描述】:

我正在尝试使用char* 数据类型来存储来自用户的字符串,代码编译正常,但在执行scanf 指令时失败, 固定数组char[10] 工作顺利,但我想知道如何改用char*

bouclesCon.c

#include "bouclesCon.h"
/... ... ...
void func_While(){
//char message[10] ="hey" ;//good
char*message="hey";//copiles but fails to execute
while(strcmp(message,"sortir")!=0){
    printf("vous avez ecrit %s\n",message);
    scanf("%s",message);
}
}

main.c

#include"bouclesCon.h"
int main()
{
  func_While();
  return 0;
}

更新

正如 carveone 和 Igor 所解释的,问题与使用 char 指针 (char*) 在运行时通过 scanf() 写入用户输入时分配足够的内存有关,相比之下,数组处理内存的方式不同。

解决方案工作代码:

`void func_While(){
    //char message[10] ="hey" ;//good
    char*message="hey";//copiles and  execute fine!!
    message=malloc(10);
    if(message==NULL){
        printf("error\n");
    }else{
        while(strcmp(message,"sortir")!=0){
            printf("vous avez ecrit %s\n",message);
            scanf("%s",message);
        }
    }
    free(message);
}
`

【问题讨论】:

  • "hey"const char[4] 类型;尝试写入由字符串文字占用的内存会表现出未定义的行为。许多编译器实际上将字符串文字存储在标记为只读的内存段中。
  • 数组不是指针,反之亦然,但在某些用法中,它会转换为第一个元素。阅读一本好的 C 书籍来学习这个重要的概念。

标签: c scanf


【解决方案1】:

正如 Igor Tandetnik 在他的评论中所说,尝试写入由字符串文字占用的内存会表现出未定义的行为。

因此行:

char*message="hey";

是问题所在。字符串“hey”可能在只读内存中,但可能不在——编译器理论上可以在堆栈上分配 4 个字节并将消息指向它。在这种情况下,您可以在粉碎堆栈之前写入 4 个字节。

最好不要猜测使用:

const char*message="hey";

如果您需要写入消息,请使用您已经完成的数组;指针和数组是可以互换的(但不完全相同,参见C FAQ),或者分配适当数量的内存:

char *message;

message = malloc(100);    /* 100 bytes allocated */
if (message == NULL)      /* The allocation failed */
   ...error...

/* Write to message */

free(message);     /* Free the 100 bytes */

【讨论】:

  • 不能在堆栈上(终生!),但可能在可写内存中。并且可以共享---
  • 我想我记得一些古老的编译器决定可以这样实现指向文字的非静态本地指针。也许我错了——至少是 20 年前的事了……
【解决方案2】:

这里是char-pointer和char数组的区别: 在声明以下代码时,正如 Igor Tandetnik 所说,您正在分配一个 const char[4] = { 'k', 'e', 'y', '\0' };在您软件的只读区域中。

char*message="hey";

在声明以下代码时,您在堆栈中分配一个 char[10](可写)并使用数组 { 'k', 'e', 'y', '\0' ... ' 对其进行初始化\0' };

char message[10] ="hey" ;

小心,当用户条目的长度保持小于 9 个字符时,第二次使用将起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-12
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多