我有指针数组“item”,我需要为它动态赋值给所有数组项具有相同的值,这是第二个for循环中显示的最后一个值
int h = 0;
char* item[6];
char x[] = "sss";
for (h = 0; h < 6; h++)
{
item[h] = (char*)malloc(sizeof(char*));
sprintf(x, "%s (%d)", "item", h);
item[h] = &x[0];
printf("item= %s\r\n", item[h]);
}
for (h = 0; h < 6; h++)
{
printf("item22222= %s\r\n", item[h]);
}
当我运行此代码时,我得到了
item= item (0)
item= item (1)
item= item (2)
item= item (3)
item= item (4)
item= item (5)
item22222= item (5)
item22222= item (5)
item22222= item (5)
item22222= item (5)
item22222= item (5)
item22222= item (5)
为什么在第二个循环中重复相同的结果?我原以为它看起来与第一个循环(item (1), item (2), ...
)类似。请帮我在代码/逻辑中找到错误。
答案 0 :(得分:1)
你正在分配一个大小为sizeof(char*)*10
的新内存块(假设你需要足够的空间容纳10个字符,而不是10个指针,应该是sizeof(char)*10
),然后将每个索引放在item
数组指向循环中的新内存块。在覆盖item
数组指向代码item[h]=&x[0]
的位置之前,一切都很好。这使得item数组中的每个指针指向相同的内存位置(x
)。只需将sprintf直接插入新内存即可。此外,因为您正在处理字符串,请确保null终止。此外,您需要确保不要在大小为10的缓冲区中写入超过9个字符。此外,除非使用c字符串,否则请使用chris的建议并使用std :: string。
int h = 0;
char* item[6];
for (h = 0; h < 6; h++)
{
item[h] = (char*)calloc(20,sizeof(char));
sprintf(item[h], "item (%d)", h);
printf("item= %s\n", item[h]);
}
for (h = 0; h < 6; h++)
{
printf("item2= %s\n", item[h]);
}
答案 1 :(得分:1)
您的代码不起作用,因为您犯了几个错误。
1)您没有为缓冲区x
分配足够的空间。
char x[]="sss";
这意味着将为x
分配3个字节(加上空值)。但是在你的sprintf
中,你会在该位置写一个更大的字符串。你很幸运它不仅仅是段错误(好吧它不适合我)。
2)你不要将字符串复制到新的空间;相反,在每个循环中,用新字符串覆盖相同的内存位(缓冲区x
)。因为每个item[h]
因此指向相同的字符串,所以它们都会在第二个循环中给出相同的结果。
稍微打破第二点(并假设你最初使x
足够大,在初始化期间加入了更多的ssssssssssss):
storage buffer x contains item[h] points to so when I print it I get
sssssssssssssssss nothing
item = item (0) storage buffer x item = item(0)
item = item (1) storage buffer x item = item(1)
item = item (2) storage buffer x item = item(2)
item = item (3) storage buffer x item = item(3)
item = item (4) storage buffer x item = item(4)
item = item (5) storage buffer x item = item(5)
当我再次绕过循环时,item [h]仍然指向x,它仍然包含
item = item (5)
要使其工作,您需要为要存储的每个字符串分配空间(而不仅仅是指向它的指针......):
#include<stdio.h>
#include<stdlib.h>
int main(void){
int h = 0;
char* item[6];
char *x;
for (h = 0; h < 6; h++)
{
item[h] = (char*)malloc(sizeof(char*));
x = (char*)malloc(50); // big enough
sprintf(x, "%s (%d)", "item", h);
item[h] = x;
printf("item= %s\r\n", item[h]);
}
for (h = 0; h < 6; h++)
{
printf("item22222= %s\r\n", item[h]);
}
}
输出:
item= item (0)
item= item (1)
item= item (2)
item= item (3)
item= item (4)
item= item (5)
item22222= item (0)
item22222= item (1)
item22222= item (2)
item22222= item (3)
item22222= item (4)
item22222= item (5)
当然,您将很难释放像这样分配的内存......但是在一个小程序中,您可以让退出时操作系统完成清理。
编辑由于malloc
操作似乎导致了问题,因此这是一种使程序正常工作的方法。它涉及“预分配”使用的内存,而不是动态地这样做。当然,这对于非常大量的数据不起作用,但是除非你发现为什么即使是非常小的malloc
也遇到问题,否则你很难运行更大的程序。所以这仅供教学使用。
回想一下,您正在尝试将文本写入“item”数组。如果我们将它作为char
的二维数组,并预先分配数据,那么我们都已设置好。诀窍:item[h][0]
的地址可以是&item[h][0]
或item[h]
。
以下是代码:
#include <stdio.h>
int main(void){
int h = 0;
char item[6][50]; // array of 6 strings of up to 50 characters
for (h = 0; h < 6; h++)
{
sprintf(item[h], "%s (%d)", "item", h);
printf("item= %s\r\n", item[h]);
}
for (h = 0; h < 6; h++)
{
printf("item22222= %s\r\n", item[h]);
}
}
我希望你有更多的运气...它给了我与以前相同的输出。
其他编辑
由于潜在问题(malloc
失败)仍然存在,我们可以尝试对其进行故障排除。请尝试运行此程序,看看会发生什么:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char* c;
int ii;
for(ii=1;ii<=50;ii++) {
c = malloc(ii);
printf("with ii = %d, c is %p\n", ii, c);
if(c!=NULL) free(c);
c = malloc(sizeof(int) * ii);
printf("allocating in chunks of 'sizeof(int)': c is now %p\n", c);
if (c!=NULL) free(c);
}
}
我们应该看/当malloc
成功或失败时(它是在您的原始代码段中工作,似乎......所以现在我们需要找出它何时/为什么会中断...)