【问题标题】:C - Memncpy/Strncpy (tried strncat too) copies 1 character less than it should, help is appreciatedC - Memncpy/Strncpy(也尝试过 strncat)复制的字符少于应有的 1 个字符,不胜感激
【发布时间】:2020-09-27 15:06:37
【问题描述】:

就像我说的,memncpy()(在 main 的中间)复制的字符比它应该复制的少 1 个字符,不知道为什么。我添加了 cmets 和图像以使其更易于理解。

    #define BIT_AMOUNT 4

char * randomBinaryGenerator(char * random){

    int randomNum, i;
    char temp;
    char * tempPtr = (char *)malloc(1 * sizeof(char));

    for(i = 0; i <= BIT_AMOUNT - 1; i++){

        randomNum = rand() % 2;
        temp = randomNum + '0';

        tempPtr = NULL;
        tempPtr = &temp;
        strcat(random, tempPtr);
    }

    return random;
}

int main(){

    srand(time(0));
    char str_bin_bitKey[BIT_AMOUNT] = "";

    char * random = (char *)malloc(BIT_AMOUNT * sizeof(char));
    char * bin_bitKey = (char *)malloc(BIT_AMOUNT * sizeof(char));

    printf("\nSize of str_bin_bitKey: %ld, Size of bin_bitKey: %ld\n", sizeof(str_bin_bitKey), sizeof(bin_bitKey));

    bin_bitKey = randomBinaryGenerator(random);    //generates 4 bit long binary number
    memcpy(str_bin_bitKey, bin_bitKey, BIT_AMOUNT);//copies 1 character less

    printf("\nbin_bitKey:     %s\n", bin_bitKey);    //4 bits
    printf("\nstr_bin_bitKey: %s\n", str_bin_bitKey);//3 bits???

    long long dec_bitKey = 0;//unimportant for now .... convertBinaryToDecimal(bin_bitKey); 

    printf("\ndec_bitKey: %lld\n\n", dec_bitKey);

    free(random);
    return 0;
}

这是输出的样子,你可以看到 str_bin_bitKey 是 3 个字符而不是 4 个:

感谢所有帮助。

【问题讨论】:

  • 请注意,tempPtr = NULL; tempPtr = &amp;temp; 正在覆盖 malloc 返回的指针(到 1 个字节!)。
  • 旁白:请使用更惯用的i &lt; BIT_AMOUNT,而不是i &lt;= BIT_AMOUNT - 1。第一个更难阅读,并且可能有缺陷
  • 在调用strcat(random, tempPtr); 中,两个参数都需要指向以空字符结尾的字符串。但是tempPtr 指向一个不包含'\0'char 变量,所以它不是一个以null 结尾的字符串。
  • 制作纯文本图像不会让任何事情更容易理解。它只会阻止选择和复制任何内容。
  • 同样在调用 strcat(random, tempPtr); random 指向由调用者 (main()) 分配给 malloc() 的内存块,但不是以空值终止的。

标签: c pointers binary size memcpy


【解决方案1】:

几个问题...

main中,数组/指针的大小需要允许nul终止符,所以它们需要是BIT_AMOUNT + 1

main 中,您的memcpy 确实复制 nul 终止符。请改用strcpy

添加起始 nul 最容易通过(例如):

*random = 0;

不要投malloc:Do I cast the result of malloc?

sizeof(char) 总是 1(根据定义),不管实际的、依赖于架构的大小(例如,char 实际上是 16 位)。所以,不要使用sizeof(char)

randomBinaryGenerator 中,tempPtr 泄漏内存。不需要malloc [甚至根本不需要tempPtr]。请改用char temp[2];

sizeof(bit_bitKey) 总是恒定的,因为它是 pointer 的大小,而 不是 它所指向的东西(即它是 not BIT_AMOUNT)。

randomBinaryGenerator 几乎需要彻底返工。


这是您的代码的注释和固定版本。我添加了:

#if 0
// old/original code
#else
// new/fixed code
#endif

帮助显示更改。

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

#define BIT_AMOUNT 4

char *
randomBinaryGenerator(char *random)
{

    int randomNum, i;
#if 0
    char temp;
    char *tempPtr = malloc(1);
#else
    char temp[2];
#endif

#if 1
    // add nul terminator
    *random = 0;
    temp[1] = 0;
#endif

#if 0
    for (i = 0; i <= BIT_AMOUNT - 1; i++) {
#else
    for (i = 0; i < BIT_AMOUNT; i++) {
#endif
        randomNum = rand() % 2;
#if 0
        temp = randomNum + '0';
        tempPtr = NULL;
        tempPtr = &temp;
        strcat(random, tempPtr);
#else
        temp[0] = randomNum + '0';
        strcat(random, temp);
#endif
    }

    return random;
}

int
main(void)
{

    srand(time(0));

// NOTE/BUG: need space for EOS terminator
#if 0
    char str_bin_bitKey[BIT_AMOUNT] = "";
    char *random = malloc(BIT_AMOUNT);
    char *bin_bitKey = malloc(BIT_AMOUNT);
#else
    char str_bin_bitKey[BIT_AMOUNT + 1] = "";
    char *random = malloc(BIT_AMOUNT + 1);
    char *bin_bitKey = malloc(BIT_AMOUNT + 1);
#endif

// NOTE/BUG: sizeof(bit_bitKey) is the size of the _pointer_ and _not_ what
// it points to (i.e. it is _not_ BIT_AMOUNT)
#if 0
    printf("\nSize of str_bin_bitKey: %ld, Size of bin_bitKey: %ld\n",
        sizeof(str_bin_bitKey), sizeof(bin_bitKey));
#endif

    // generates 4 bit long binary number
    bin_bitKey = randomBinaryGenerator(random);

    // copies 1 character less
#if 0
    memcpy(str_bin_bitKey, bin_bitKey, BIT_AMOUNT);
#else
    strcpy(str_bin_bitKey, bin_bitKey);
#endif

    // 4 bits
    printf("\nbin_bitKey:     %s\n", bin_bitKey);
    // 3 bits???
    printf("\nstr_bin_bitKey: %s\n", str_bin_bitKey);

    // unimportant for now .... convertBinaryToDecimal(bin_bitKey);
    long long dec_bitKey = 0;

    printf("\ndec_bitKey: %lld\n\n", dec_bitKey);

    free(random);

    return 0;
}

这是一个经过清理和改进的版本。请注意,randomBinaryGenerator 更快/更好 完全不使用 strcat

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

#define BIT_AMOUNT 4

char *
randomBinaryGenerator(char *random)
{

    int randomNum, i;

    for (i = 0; i < BIT_AMOUNT; i++) {
        randomNum = rand() % 2;
        random[i] = randomNum + '0';
    }

    // add nul terminator
    random[i] = 0;

    return random;
}

int
main(void)
{

    srand(time(0));

    char str_bin_bitKey[BIT_AMOUNT + 1];
    char *random = malloc(BIT_AMOUNT + 1);
    char *bin_bitKey = malloc(BIT_AMOUNT + 1);

    // generates 4 bit long binary number
    bin_bitKey = randomBinaryGenerator(random);

    strcpy(str_bin_bitKey, bin_bitKey);

    // 4 bits
    printf("\nbin_bitKey:     '%s'\n", bin_bitKey);

    // 3 bits???
    printf("\nstr_bin_bitKey: '%s'\n", str_bin_bitKey);

    // unimportant for now .... convertBinaryToDecimal(bin_bitKey);
    long long dec_bitKey = 0;

    printf("\ndec_bitKey: %lld\n\n", dec_bitKey);

    free(random);

    return 0;
}

【讨论】:

  • 哇,非常感谢你 :) 老实说,我发现内存分配有点过于混乱,因此导致我编写混乱的代码。我真的很感谢你的帮助。如果你不介意你能指出我应该阅读的概念以及我应该检查和研究的资源的正确方向吗,到目前为止我喜欢 C,但它有时对我来说肯定有点太复杂了.上帝保佑:)
  • 这个答案有内存泄漏,因为char *bin_bitKey = malloc(BIT_AMOUNT + 1);分配的内存永远不会通过调用free(bin_bitKey);返回
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2016-04-19
  • 2012-05-12
  • 1970-01-01
  • 2014-10-27
  • 2011-10-13
相关资源
最近更新 更多