c - memcpy 在这个程序中到底做了什么?

标签 c string malloc memcpy realloc

我正在编写一个程序,其中的输入将从标准输入中获取。第一个输入将是一个整数,表示要从标准输入读取的字符串数。 我只是将字符串逐个字符地读取到动态分配的内存中,并在字符串结束时显示它。
但是当字符串大于分配的大小时,我将使用 realloc 重新分配内存。 .但即使我使用 memcpy,该程序也能正常工作。不使用 memcpy 是未定义的行为吗?但是例子Using Realloc in C不使用 memcpy。那么哪一个是正确的方法呢?下面显示的程序是否正确?

/* ss.c
 * Gets number of input strings to be read from the stdin and displays them.
 * Realloc dynamically allocated memory to get strings from stdin depending on
 * the string length.
 */

#include <stdio.h>
#include <stdlib.h>

int display_mem_alloc_error();

enum {
    CHUNK_SIZE = 31,
};

int display_mem_alloc_error() {
    fprintf(stderr, "\nError allocating memory");
    exit(1);
}

int main(int argc, char **argv) {
    int numStr;                  //number of input strings
    int curSize = CHUNK_SIZE;    //currently allocated chunk size
    int i = 0;                   //counter
    int len = 0;                 //length of the current string
    int c;                       //will contain a character
    char *str = NULL;            //will contain the input string
    char *str_cp = NULL;         //will point to str
    char *str_tmp = NULL;        //used for realloc

    str = malloc(sizeof(*str) * CHUNK_SIZE);
    if (str == NULL) {
        display_mem_alloc_error();
    }    
    str_cp = str;   //store the reference to the allocated memory

    scanf("%d\n", &numStr);   //get the number of input strings
    while (i != numStr) {
        if (i >= 1) {   //reset
            str = str_cp;
            len = 0;
        }
        c = getchar();
        while (c != '\n' && c != '\r') {
            *str = (char *) c;
            printf("\nlen: %d -> *str: %c", len, *str);
            str = str + 1;
            len = len + 1;
            *str = '\0';
            c = getchar();
            if (curSize/len == 1) {
                curSize = curSize + CHUNK_SIZE;
                str_tmp = realloc(str_cp, sizeof(*str_cp) * curSize);
                if (str_tmp == NULL) {
                    display_mem_alloc_error();
                }
                memcpy(str_tmp, str_cp, curSize);    // NB: seems to work without memcpy
                printf("\nstr_tmp: %d", str_tmp);
                printf("\nstr: %d", str);
                printf("\nstr_cp: %d\n", str_cp);
            }
        }
        i = i + 1;
        printf("\nEntered string: %s\n", str_cp);
    }
    return 0;
}

/* -----------------
//input-output
gcc -o ss ss.c
./ss < in.txt

// in.txt
1
abcdefghijklmnopqrstuvwxyzabcdefghij

// output
// [..snip..]
Entered string:
abcdefghijklmnopqrstuvwxyzabcdefghij
-------------------- */

谢谢。

最佳答案

您的程序不太正确。您需要删除对 memcpy 的调用,以避免偶尔出现难以诊断的错误。

来自realloc man page

The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes

因此,您不需要在realloc 之后调用memcpy。事实上,这样做是错误的,因为您之前的堆单元可能已在 realloc 调用中被释放。如果它被释放,它现在指向具有不可预测内容的内存。

关于c - memcpy 在这个程序中到底做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13083575/

相关文章:

c - 我不明白为什么我的 WRITE 函数(C 语言)不能使用字符 ('c' )?

php - PHP中变量扩展与sprintf的性能

java - 正则表达式 - 搜索一个单词并使用不区分大小写的相同单词替换它

C:内存使用和数组问题

c - 如何用C写这个

c - 为什么 GCC 会针对错误的 printf 格式说明符显示重复警告?

c - 程序以代码 0320 退出?

vb.net - VB.NET中连接字符串时+和&的区别

c - 释放 C 中的 2D 数组。 "double free or corruption"和 "invalid next size"

C Sysmalloc 断言失败