将值赋给指针数组

时间:2013-06-18 22:04:07

标签: c++

我有指针数组“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), ...)类似。请帮我在代码/逻辑中找到错误。

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成功或失败时(它是在您的原始代码段中工作,似乎......所以现在我们需要找出它何时/为什么会中断...)