我正在尝试创建和存储char*
数组。
所以,首先我尝试了这个:
int main() {
char* values[3];
values[0] = "Hello";
values[1] = "Mew meww";
values[2] = "Miau miau =3";
for(int i=0; i<sizeof(values); i++)
printf("%s", values[i]);
}
它适用于此OUTPUT:
您好 喵喵 Miau miau = 3
如果我尝试:
printf("%s", "Tamaño del diccionario: ");
int tam;
scanf("%i", &tam);
char* dic[tam];
Word words[tam];
for(int i=0; i<tam; i++)
{
printf("Palabra %d: ",(i+1));
scanf("%32s", &dic[i]);
}
for(int i=0; i<tam; i++)
{
printf("%s",dic[i]);
printf("\n");
}
显示不可读的内容,例如&#34; 0xassdfsdf&#34;
我该怎样做才能将它存储在内存中?
答案 0 :(得分:2)
一个问题是
scanf("%32s", &dic[i]);
应该是
scanf("%32s", dic[i]);
因为数组包含指向存储的指针,而不是存储本身,你应该传递给scanf
的是这个指针。实际上,char*
只是一个4字节的指针。数组char* dic[tam]
包含一些这样的指针,因此dic[0]
是指向char
的4字节指针,&dic[0]
是此指针的地址。
scanf("%32s", &dic[i]);
只是覆盖此指针并在其后破坏内存。
另一个问题是你没有初始化数组,所以它没有指向任何存储。
char* dic[tam];
此处数组包含指向内存中随机位置的指针。
scanf("%32s", &dic[i]);
很可能这完全失败了。因此,在printf
中,您可以打印指向内存中随机位置的指针。
(坏)解决方案是:
for(int i=0; i<tam; i++)
{
printf("Palabra %d: ",(i+1));
dic[i] = new char [1000]; // here you assign it some storage
scanf("%32s", dic[i]); // NOT &dic[i]
}
或(略好)
for(int i=0; i<tam; i++)
{
printf("Palabra %d: ",(i+1));
char buffer [1000]; // temporal storage arguably large enough
scanf("%32s", buffer);
dic[i] = new char [strlen (buffer) + 1]; // storage of the right size to hold the string
strcpy (dic[i], buf); // copy the data to this new storage
}
答案 1 :(得分:2)
#include <stdio.h>
#include <stdlib.h>
int main(){
char* values[3];
values[0] = "Hello";
values[1] = "Mew meww";
values[2] = "Miau miau =3";
for(int i=0; i<sizeof(values)/sizeof(*values); i++)
printf("%s\n", values[i]);
printf("%s", "Size for dictionary: ");
int tam;
scanf("%i", &tam);
char *dic[tam];
for(int i=0; i<tam; i++){
printf("Palabra %d: ",(i+1));
dic[i] = malloc(33);
scanf("%32s", dic[i]);
}
for(int i=0; i<tam; i++){
printf("%s\n", dic[i]);
free(dic[i]);
}
return 0;
}
答案 2 :(得分:0)
对于这两个示例,要理解的关键是char *
值将字节的地址存储在内存中。按照惯例,C字符串表示为指向字符串第一个字节的指针,其中空字节标记结尾。当您将常量字符串分配到数组中时,编译器会分配必要的内存并将指针放入您的数组中,但是当您不使用常量时,您有责任分配缓冲区来存储字符串,然后将该指针存储在排队自己。
在你的第二个例子中,你已经为char
的几个指针分配了存储空间,但你没有让那些指针引用有效的缓冲区,所以使用return garbage或者程序崩溃来访问它们。有(至少)两种方法来解决这个问题:要么在堆栈上分配固定大小的缓冲区并在那里存储数据,要么使用malloc
从堆中动态分配内存。
前者具有自动处理缓冲区释放的优点,但需要您在编译时决定为每个字符串分配多少内存:
char* dic[tam];
char buf[tam * 32]; // allocate 32 bytes per element.
for (int i = 0; i < tam; i++) {
// Make the pointers in ``dic`` refer to 32-byte offsets into the buffer.
dic[tam] = &(buf[tam * 32]);
}
您还可以使用malloc
动态分配。你实际上也可以用这种方式分配一个大的tam * 32
缓冲区,但为了举例说明,如何为每个元素分配一个单独的缓冲区:
char* dic[tam];
for (int i = 0; i < tam; i++) {
// Allocate 32 bytes per element.
// (This value can be decided at runtime, if you want.)
dic[tam] = malloc(32);
}
但由于这使用malloc
,因此您需要确保在返回之前清理此内存以避免内存泄漏。例如在你的日常工作结束时:
for (int i = 0; i < tam; i++) {
// de-allocate the buffer we allocated earlier
free(dic[tam]);
}
(这种在循环中多次调用malloc
的方法如果你做了很多事,也可能导致内存碎片化,但这是一个不值得为小程序担心的高级主题。)< / p>