【问题标题】:2D arrays. First index wrong, all others correct二维数组。第一个索引错误,其他所有正确
【发布时间】:2012-05-17 19:11:00
【问题描述】:

我有一个奇怪的问题,我不知道如何解决它。

我正在读取一个 50x50 字符的文本文件,并希望将其写入一个 50x51 的动态数组(用 '\0' 填充第 51 个插槽)。

之后,我将整个数组打印到控制台上。 它应该显示 50 行,每行 50 个字符,因为这是输入。

它也很好用——除了第一行。由于某种原因总是错误的。

#define FIELD_SIZE 50
int main(int argc, char** args){
    char* data = ReadFile("start.txt");

    char** map = (char**) malloc( FIELD_SIZE );

    if(map==NULL)
        __debugbreak();

    {
        int i;
        for(i = 0; i < FIELD_SIZE; i+=1){
            map[i] = (char*) malloc(FIELD_SIZE+1);

            if(map[i]==NULL)
                __debugbreak();
            //(FIELD_SIZE+1) in order to skip the '\n' at the end of each line.
            memcpy( &map[i][0], &data[i*(FIELD_SIZE+1)], FIELD_SIZE);
            map[i][FIELD_SIZE] = '\0';
        }
    }


    {
        int i;
        for(i = 0; i < FIELD_SIZE; i+=1){
            printf("%s\n", map[i]); //<-- prints something bad for i==0
        }
    }

    free(data);

    return 0;
}

这是我的控制台在程序执行后的样子: 第一行也应该是“aaaaaaaaaaaaaa ...”。 所以这似乎是一个错误的指针或其他东西。

如果我将 FIELD_SIZE 减小到 20(并分别读取 20x20 文本文件),它可以正常工作。

我没有看到数组大小和第一个索引之间的联系不起作用。由于 malloc 从未返回 0,因此分配没有问题。

我正在使用VS2010 C++编译程序,但我必须将自己限制在C子集。

【问题讨论】:

  • 你确定你的文件没问题吗?
  • 该文件是一个 ANSI 编码的常规文本文件(使用 np++)。它只包含 20 行,每行 20 个 a。由于除第一行之外的所有内容都有效,我认为问题不直接在于读取文件。正如我所说,如果我减少 FIELD_SIZE 一切正常,所以它不是文件中的“隐藏”有问题的字符或类似字符。
  • 添加了要发布的图片,这样即使引用的图片网站不再有效,未来的访问者也能理解问题。
  • 出于好奇,如果在将行读入数组后立即打印出来会怎样?
  • @Michael - 实际上打印了正确的字符串。所以有证据表明出错的不是文件读取。

标签: c arrays visual-studio-2010 pointers


【解决方案1】:

char** map = (char**) malloc( FIELD_SIZE );

char** map = (char**) malloc( FIELD_SIZE * sizeof(char*));

我不知道这是否是您代码中的错误。 您分配了 50 个字节,但在 map 中需要 50 个字节 x 4 个字节/指针。

【讨论】:

  • 愚蠢的我。是的,就是这样,我忘记了 char*。令人讨厌的是它只窃听了第一个插槽。
  • 如果你有一个测试演员,比如'abcdefghijkalalsdkfmasdl',即很多随机字符,它可能会弹出而不是一堆a。随机字符串可能会显示我希望的不匹配地址,但经过一整天的编码之后,仍然很难确定这样的事情。
  • char **map = malloc(FIELD_SIZE * sizeof *map); 会更好。演员表不是必需的(在 C 中),只是增加了噪音。 *map的类型是char *;并非如此,但如果您更改了map 的类型,您就不必担心在malloc 调用中复制该更改。
  • @John Bode 演员阵容是必要的,这是第一,sizeof *map is 噪音,这是第二
  • @Ulterior - 自 C89 以来,C 中不需要强制转换;一个void * 可以转换为任何其他对象指针类型没有一个。在 C++ 中它仍然是必需的,但您不应该在 C++ 代码中使用 malloc。我对sizeof *map 的理由仍然成立;如果您更改 map 的类型,则不必在 malloc 调用中复制更改。
【解决方案2】:

很快就会注意到。在这种情况下,它可能是无用的。 Memcpy 将指针的地址而不是引用值作为其源,因此通常您不应该按照您的方式使用它。据我所知,您正在尝试一次复制一行。

memcpy( map[i], &data[i*(FIELD_SIZE+1)], FIELD_SIZE);

尝试一下,尽管它可能无法解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2015-12-06
    • 2012-04-10
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2017-06-27
    • 2019-05-22
    相关资源
    最近更新 更多