【问题标题】:printf only display 24 characters of char*printf 只显示 char* 的 24 个字符
【发布时间】:2016-10-18 09:33:45
【问题描述】:

我正在做一个创建一个可以上网的机器人的项目。

我必须用 C 语言编写它,现在我专注于选择它的去向地址(从文件中的列表中选择)。这可以正常工作,但是当我显示机器人选择的地址时,有些地址会被截断为 24 个字符并以“!”结尾这使得代码无法用于长地址。有谁知道它可能会出现在哪里?

程序:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>

int main() {
  FILE* file = fopen("test.txt", "r+");

  char *line = NULL;
  char *tab[1023];
  int tailleTab = 0;

  line = malloc(sizeof(*line));

  if(line == NULL)
    return(EXIT_FAILURE);

  while((fgets(line, 1023, file)) != NULL ) {
    if(line[0] != '#' && line[0] != '\n') {
      tab[tailleTab] = line;
      line = malloc(sizeof(*line));
      tailleTab++;
    }
  }

  srand(time(NULL));
  int n = rand()%tailleTab;
  printf("\n%d = %.32s\n", n, tab[n]);
  printf("%s\n", tab[n]);
  fclose(file);
}

从中选择地址的文件:

www.google.com
www.wikipedia.org
www.dahunicorn.xyz
www.cloudimperiumgames.com
www.robertspaceindustries.com
www.candybox2.net
www.42.com
www.1337.com

【问题讨论】:

  • 请分享您的意见 - 我们无法猜测!另外,请分享您的调试观察。
  • 请在使用后释放分配。在简单的测试 sn-ps 中也这样做的好习惯。

标签: c string printf malloc


【解决方案1】:

主要问题是这样的:

line = malloc(sizeof(*line));

这只分配一个单个字符给line。表达式*linechar,这意味着您分配sizeof(char) 字节,而sizeof(char) 被定义为始终为1

这意味着您对fgets 的调用将超出您分配的内存的范围,并且您将有未定义的行为

实际上没有理由动态分配line。而是将其创建为一个数组,然后在将其保存在tab 数组中时使用strdup。要么分配更多内存(1023 是一个很好的数字,因为这是您传递给 fgets 的数量)。

【讨论】:

    【解决方案2】:

    正如在另一个答案中已经解释的那样,使用以下代码:

    line = malloc(sizeof(*line));
    

    您正在使用malloc 在堆上分配单个char,因为表达式*line 等效于char(因为line 被声明为char *)。

    我会使用命名常量来简化您的代码,而不是像1023 这样在代码中传播的幻数(这会使其更难维护),此外只是为临时@ 保留空间987654329@缓冲区在栈上而不是在堆上动态分配,例如:

    /* Instead of: line = malloc(sizeof(*line)); */
    #define LINE_MAX_SIZE 1024
    char line[LINE_MAX_SIZE];
    

    也考虑做:

    #define TAB_MAX_ITEMS /* 1023 or whatever */
    char* tab[TAB_MAX_ITEMS];
    

    while 循环中考虑使用LINE_MAX_SIZE 代替幻数1023

    while ((fgets(line, LINE_MAX_SIZE, file)) != NULL ) {
    

    您可能还想对tab 数组中的索引添加检查,以避免缓冲区溢出:

    if (tailleTab >= TAB_MAX_ITEMS) {
        /* Index out of range */
        ...
    }
    
    /* tailleTab is a valid index.
     * Deep-copy the line read in the temporary buffer
     * and save a pointer to the copy into the tab array.
     */
    tab[tailleTab] = strdup(line);
    

    在生产代码中,您还应该遍历存储在tab 数组中的指针,并在它们上调用free 以释放在堆上分配的内存。

    【讨论】:

      猜你喜欢
      • 2012-05-05
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多