【问题标题】:Pointers and Reallocation in CC中的指针和重新分配
【发布时间】:2014-09-30 22:05:17
【问题描述】:

我对 C 还很陌生;上课3周。我在使用指针时遇到了一些麻烦,并且确信可能有一个简单的解决方法。所以基本上,这个程序应该从输入文件中读取一个单词,将它存储在一个具有内存分配的指针数组中,打印该单词和该单词的规范化形式(不相关的过程),然后重新分配空间以便随着更多单词的输入,指针数组将增长。但是,我在打印要打印的单词和要重新分配的数组时遇到了一些麻烦(我目前将其设置为固定大小,只是为了解决整个打印方面的问题)。如果我的变量声明有问题,或者我只是犯了一个愚蠢的错误,请告诉我(我相信这可能是两者的结合)。同样,我对 C 很陌生,所以如果这是一个简单的问题,我深表歉意。

char * word_regular[100];
char * word_norm[100];

int main (int argc, char * argv[])
{

    if (argc != 2){
        printf("You have not entered a valid number of files.\n");
        exit(1);
    }

    FILE * f_in = fopen(argv[1],"r");
    int i = 0;
    char word[512];
    char norm_word[512];

    while(fscanf(f_in, "%s", word) != EOF) {
        if (is_valid_entry(word)) {
            word_regular[i] = malloc(sizeof(char) * strlen(word) + 1);
            strcpy(word_regular[i],word);
            printf("%s\n",*word_regular[i]);
            word_norm[i] = malloc(sizeof(char) * strlen(norm_word) + 1);
            normalize(word, norm_word);
            strcpy(word_norm[i],norm_word);
            printf("%s\n", *word_norm[i]);
            i++;        

【问题讨论】:

  • printf("%s\n",*word_regular[i]); --> printf("%s\n", word_regular[i]);, printf("%s\n", *norm_word[i]); 同上。也没有读取norm_word。但使用strlen(norm_word)
  • word_norm[i] = malloc(sizeof(char) * strlen(norm_word) + 1); normalize(word, norm_word); : 交换位置。
  • 当我尝试只使用 word_regular[i] 打印 f 时,我收到错误“'%s\n' 需要类型 char * 但参数 2 的类型为 int。知道我如何能够做到解决这个问题? word[] 是 char 类型,所以我假设将其地址复制到 word_regular 会使 word_regular[i] 也属于 char 类型。
  • word_regular[i] 的类型是char*。 (因为char * word_regular[100];
  • 我就是这么想的。但是,由于某种原因,它给了我一个 int 类型的错误。当我使用 gdb 浏览它时,它看起来不像 strcpy 正在运行,因此没有地址被复制到 word_regular 指向的地址中。任何可能的解决方案?

标签: c arrays pointers realloc


【解决方案1】:

当前代码存在的一些问题(忽略动态大小需要而不是修复,因为您已经说过要使用它进行调试),

printf("%s\n",*word_regular[i]);

%s 需要一个 char * 来打印,所以应该是

printf("%s\n",word_regular[i]);

对于第二个printf,由于norm_word本身是一个char数组,

你应该简单地使用

printf("%s\n", &norm_word[i]);

如果要打印从第 i 个索引开始的字符串。

更新: 一个快速提示是注意是否使用字符串复制 \0。因为你的 api 调用,比如 strlen 会超越字符串崩溃(或者最糟糕的静默),除非它是空终止的。

【讨论】:

  • printf("%s\n", &norm_word[i]); --> printf("%s\n", word_norm[i]);
  • 是的,我只是想修复间接而不是用不同的数组名称替换
【解决方案2】:
  1. printf 调用的问题在于,当您尝试打印一个字符串。

  2. 如果要动态增长数组,首先需要动态分配它,所以不要声明指针数组:

    char * word_regular[100];
    char * word_norm[100];
    

    你需要声明指向指针的指针:

    char ** word_regular;
    char ** word_norm;
    

    为它们分配一个初始缓冲区(在函数中,例如 main):

    word_regular = malloc(sizeof(char *) * INITIAL_AMOUNT);
    

    然后根据需要重新分配它们。

    word_regular = realloc(word_regular, sizeof(char *) * new_amount);
    

    您将需要跟踪数组中的指针数量,当然要正确释放它们...

【讨论】:

  • 或者用char ** word_norm = NULL初始化并且只使用realloc()就像word_regular = realloc(word_regular, new_amount);一样
  • 同意初始化,我觉得reallocing第一次是风格问题。在解释时,为了清楚起见,我更喜欢单独做(至少在我的脑海里:))
  • 任何一种方式都适合我,但你的 realloc(sizeof(char *) * new_amount) 得到 1 个参数。它应该是 2。
猜你喜欢
  • 2015-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
相关资源
最近更新 更多