【问题标题】:stack Uninitialised value was created by a stack allocationstack 未初始化的值是由堆栈分配创建的
【发布时间】:2013-09-15 07:19:44
【问题描述】:

下面的代码单播一个带有一些信息的 udp 数据包。我明白了

Syscall param socketcall.sendto(msg) points to uninitialised byte(s)  in main in main.c:104

Address 0xbec64e7b is on thread 1's stack Uninitialised value was created by a stack allocation  1: log_msg_send in main.c:29

当我将数据传递到下面的函数时来自 valgrind 的消息。

谁能告诉我什么是未初始化的?

代码:

#define BUFSIZE 512

void log_msg_send(char *message, char *next_hop)
{ // line 29***************************

  int r = 0, error_count = 0;

  struct sockaddr_in si_other;
  int s, slen = sizeof(si_other);
  char buf[strlen(message) + 1];
  strcpy(buf, message);
  buf[strlen(message)] = '\0';
  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  {
    fprintf(stderr, "socket() failed - line817\n");
    exit(1);
  }

  memset((char *) &si_other, 0, sizeof(si_other));
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(12345);

  /****************NORMALIZE THE DOT IPV4 ADDRESS********************/ //eg. 010.000.001.050 = 10.0.1.50
  int parts[4];
  sscanf(next_hop, "%d.%d.%d.%d", parts + 0, parts + 1, parts + 2, parts + 3);
  char *out = NULL;
  asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
  /****************NORMALIZE THE DOT IPV4 ADDRESS_END****************/

  if (inet_aton(out, &si_other.sin_addr) == 0)
  {
    fprintf(stderr, "inet_aton() failed - line 825\n");
    exit(1);
  }

  if (sendto(s, buf, BUFSIZE, 0, (struct sockaddr *) &si_other, slen) == -1)
  {
    fprintf(stderr, "sendto() failed - line830\n");
    exit(1);
  }
  free(out);

  r = close(s);
  while (r < 0)
  { //error handling for sendto
    usleep(500000);
    if (++error_count == 20)
    { //10 times itteration
      fprintf(stderr, "errno:%s - socket closing error - line 1091\n ",
          strerror(errno));
      exit(1);
    }
    r = close(s);
  }
  error_count = 0;

}

int main()
{
  char nexthop[16] = "010.105.001.204";
  char *gateway_ID[2] =
  { "010.203.005.012", "010.235.011.041" };
  char message[720] =
  { '\0' }; // 20 msg
  char msg_to_send[1000] =
  { '\0' };
  srand(time(NULL));
  int no_of_nodes = 0;
  int i;

  while (1)
  {
    memset(message, 0, sizeof(message));
    memset(msg_to_send, 0, sizeof(msg_to_send));
    no_of_nodes = rand() % 19 + 1;

    for (i = 0; i < no_of_nodes; ++i)
    { //prepare the message
      if (i == 0)
      {
        sprintf(message, "100.100.100.%03d%d%02d", (rand() % 255), (rand() % 3),
            (rand() % 100));
      }
      else
      {
        sprintf(message, "%s100.100.100.%03d%d%02d", message, (rand() % 255),
            (rand() % 3), (rand() % 100));
      }

    }

    snprintf(msg_to_send, 2 + 16 + 5 + strlen(message) + 1, "12%s%05d%s",
        gateway_ID[(rand() % 2)], strlen(message), message);
    //     printf("%s\n\n",msg_to_send);
    log_msg_send(msg_to_send, nexthop); // line 104 ********************************

    // usleep(15000);
  }

  return 0;
}

【问题讨论】:

  • 我以前没见过这个吗?

标签: c initialization stack valgrind


【解决方案1】:

我会说 Valgrind 抱怨缺少代码以完全log_msg_send() 中初始化 char buf[strlen(message) + 1]

要解决这个问题,只需添加

memset(buf, 0, sizeof(buf));

buf 的声明之后。


此外,代码没有将正确大小的缓冲区传递给sendto()

要修复此更改的大小:

if (sendto(s, buf, BUFSIZE, 0, (struct sockaddr *) &si_other, slen) == -1)

成为:

if (sendto(s, buf, sizeof(buf), 0, (struct sockaddr *) &si_other, slen) == -1)

最后,与 Valgrind 问题无关:

  • sendto() 的最后一个参数应为socklen_t

  • 通过strlen() 的结果的printf() 需要z 长度修饰符,因为它正在接收size_t

【讨论】:

  • 我添加了它,但仍然从 valgrind 收到相同的消息。
  • memset 有何不同?下一行strcpy(buf, message); 必须写入buf 的所有条目。
【解决方案2】:

我在程序中遇到了类似的错误。原来 Valgrind 抱怨我在 char* 上使用 sscanf() 并没有终止 \0,尽管我应该只在 \n 之前阅读,如下所示。

sscanf(buf, "%[^\n]", str);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2011-01-11
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多