C- Memcpy在此程序中的工作能力



我正在编写一个程序,其中输入将从stdin中获取。第一个输入将是一个整数,它说要从stdin读取的字符串数。我刚刚将字符串字符读为动态分配的内存,并在字符串结束后将其显示。
但是,当字符串大于分配的尺寸时,我将使用Realloc重新定位内存。但是,即使我使用memcpy,该程序也有效。不使用memcpy是不确定的行为吗?但是在C中使用Realloc的示例不使用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("%dn", &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 = '';
            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: %dn", str_cp);
            }
        }
        i = i + 1;
        printf("nEntered string: %sn", str_cp);
    }
    return 0;
}
/* -----------------
//input-output
gcc -o ss ss.c
./ss < in.txt
// in.txt
1
abcdefghijklmnopqrstuvwxyzabcdefghij
// output
// [..snip..]
Entered string:
abcdefghijklmnopqrstuvwxyzabcdefghij
-------------------- */

谢谢。

您的程序不太正确。您需要删除与memcpy的呼叫,以避免偶尔诊断出bug。

来自Realloc Man Page

realloc()函数更改了指向的内存块的大小 由PTR到大小字节。内容将在该范围内保持不变 从该地区的开始到新旧的最低限度 尺寸

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

c11标准(PDF),第7.22.3.4节:

realloc函数交易了PTR指向的旧对象,并将指针返回到具有大小规定大小的新对象。新对象的内容应与Dealllocation之前的旧对象相同,直到新尺寸和旧尺寸的较小。超出旧对象大小的新对象中的任何字节都有不确定的值。

简而言之,memcpy是不必要的,确实是错误的。错误的原因有两个:

  • 如果realloc具有free D您以前的内存,则您正在访问不是您的内存。
  • 如果realloc刚刚放大了您以前的内存,则为memcpy提供了两个指向同一区域的指针。memcpy在其两个输入指针上都有restrict预选赛,这意味着如果它们指向同一对象,则是未定义的行为。(旁注:memmove没有此限制)

realloc放大为字符串保留的内存大小。如果可以在不移动数据的情况下扩大它,则这些将保持到位。如果不能,则它会在啤酒记忆库中进行malloc,而memcpy本身是上一个内存库中包含的数据。

简而

从"人"页面:

realloc()函数试图更改分配的大小 由PTR到大小,然后返回PTR。如果没有足够的空间 放大由PTR指向的内存分配,Realloc()创建了一个新的 分配,副本同样适合PTR指向的旧数据 转到新的分配,释放旧分配,然后返回指针 分配的内存。如果ptr为null,则realloc()与呼叫相同 到malloc()大小字节。如果大小为零,并且PTR不是零,则是新的, 最小尺寸的对象是分配的,原始对象已释放。什么时候 延长由Calloc(3)分配的区域,Realloc(3)不瓜兰 - Tee额外的内存也为零。

相关内容

  • 没有找到相关文章

最新更新