在C语言中动态分配一个字符串数组 - Malloc

6

我一直在尝试理解malloc和字符串,有谁能帮我解决这个问题吗?我遇到了一个错误:坏的指针。

char password[100];
char *key[2];   
int textlen, keylen, i, j, k, t, s = 0;

printf("password:\n") ;   
scanf("%s",password);

keylen = strlen(password) + 1;

for(i=0; i < keylen; i++)
{                
    key[i] = (char*)malloc(keylen * sizeof(char));
    strcpy(key[i], password);
}

printf("The key is:\n\t %s", key);

1
什么是“坏指针错误”?请始终粘贴错误消息和您的输入,以便可以重现该行为。 - Zeta
关键数组有两个条目,但是只要密码超过一个字符,您就会立即写入第二个元素。 - SirDarius
不确定你想做什么。无论如何,如果“password”字符串大于一个字符,“keylen”将大于1,因此“key [i]”将超出边界访问。 - Nemanja Boric
为什么你在使用for循环?这样会在键(key)中创建大量的字符串,而不是2,并导致溢出。 - Oleg Olivson
@Zeta - 我已经逐步执行了代码,当我到达'key [i] =(char *)malloc(keylen * sizeof(char));'时,我得到了“0xcccccccc <Bad Ptr>”的错误提示,而我的输入是“fortification”。 - Dex Dave
@SirDarius 好的,我该如何解决这个问题? - Dex Dave
2个回答

16

我认为你需要尝试理解自己想要实现的目标。你不需要key[2]数组,我认为你会因此而感到困惑,因为你还不了解指针的工作原理。以下内容应该可以正常运行(未经测试)。

// Allow a password up to 99 characters long + room for null char
char password[100];
// pointer to malloc storage for password
char *key;   
int textlen, keylen, i, j, k, t, s = 0;

// Prompt user for password
printf("password:\n") ;   
scanf("%s",password);

// Determine the length of the users password, including null character room
keylen = strlen(password) + 1;

// Copy password into dynamically allocated storage
key = (char*)malloc(keylen * sizeof(char));
strcpy(key, password);

// Print the password
printf("The key is:\n\t %s", key);

好的。更重要的是,你明白为什么你的例子会崩溃吗? - djgandy
1
是的,指针的声明错误了,循环也有错误。再次感谢您的帮助。 - Dex Dave
为什么在C代码中要使用malloc()进行强制转换?此外,scanf()是不安全的。 - galois
1
我的例子是对原始代码所需最少的修复。我不想通过完全重写他的整个代码来让OP感到困惑。如果这是代码审查,我会同意你的观点。 - djgandy

5
您所面临的问题在这里:

 printf("The key is:\n\t %s", key);

你正在将指针数组传递给printf,而你想要做的是:
 printf("The key is:\n\t %s", key[0]);

另一个问题是您分配了与密码中字符数量相同的指针,因此您覆盖了保留的指针数组,因为“key”仅有两个指针的空间,不足以容纳N个指针,这是导致“错误指针”的主要原因。
还有一件事与此错误无关,即您不应将“malloc”转换为所需大小,也不需要乘以“sizeof(char)”,因为根据定义,其始终为1。

你不认为问题在于如果你输入一个3个或更多字符的密码,key[i]会尝试写入无效的内存吗? - djgandy
1
是的,那是另一个问题。我的打字速度不如代码中的错误快。 :) - Devolus
1
这是 keylen 循环。 - Devolus
如果密码超过2个字符,您将会溢出密钥数组。 - djgandy
@Devolus:"你不应该将 malloc 进行类型转换"。为什么呢?malloc 返回的是 void* 类型,void* 类型会自动转换为 char* 吗? - jnovacho
1
void * 在 C 中是自动兼容的,当你进行强制类型转换时,可能会隐藏一些微妙的错误。https://dev59.com/dHRB5IYBdhLWcg3wgHWr - Devolus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接