memcpy垃圾数据被打印后

时间:2018-07-11 07:53:23

标签: c

我最近试图创建一个复制字符串的函数,例如:ip:“ apple” count = 5,输出:“ appleappleappleappleappleapple”

char *ch = "apples"
ch = cpy_data(ch, 6, 20);  

char *cpy_data(char *ip_str, int in_len, out_len)
{
    char *c = malloc(out_len);
    memset(c, 0, out_len);
    int rem, n;
    rem = out_len % in_len;
    n = 0;
    while(n < out_len){
        memcpy(&c[n], ip_str, in_len);
        n += in_len;
    }
    if (rem)
        memcpy(&c[n], ip_str, rem);
    printf("%s \n" c);
    return c;
}
OutPut: applesapplesapplesapplesaph�

输出len大大大于预期的输入,并且一些尾随的垃圾数据正在打印。

2 个答案:

答案 0 :(得分:1)

您问题中的代码包含约5个语法错误。最好显示出您确切使用的代码。

一旦固定为语法正确的C,您的程序就会尝试向malloc分配的块中写入超出合适范围的数据:https://taas.trust-in-soft.com/tsnippet/t/9c2ce34f

Frankie_C在注释中指出,您可能希望为最终的'\0'保留空间,但这不足以定义该程序:该程序中还存在逻辑错误尝试再复制in_len个字符,只要还有余下一个字符:https://taas.trust-in-soft.com/tsnippet/t/3a2b848b

我就像Karthick的答案一样将循环条件更改为while (n < out_len - rem) {。现在的问题是传递给printf("%s"的字符数组没有以最后的'\0'结尾:https://taas.trust-in-soft.com/tsnippet/t/7c1ca032

必须写最后的\'0'。由于目标块是由malloc分配的,因此不能保证将其初始化为0,因此仅在末尾留一个字符是不够的。您还必须将最后一个字符显式设置为'\0',例如:

c[out_len] = '\0'; 

最后,不会产生未定义行为的程序修改版本为(https://taas.trust-in-soft.com/tsnippet/t/dea9e8b2):

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

char *cpy_data(char *ip_str, int in_len, int out_len)
{
    char *c = malloc(out_len + 1);
    memset(c, 0, out_len);
    int rem, n;
    rem = out_len % in_len;
    n = 0;
    while(n < out_len - rem){
        memcpy(&c[n], ip_str, in_len);
        n += in_len;
    }
    if (rem)
        memcpy(&c[n], ip_str, rem);
    c[out_len] = '\0';    
    printf("%s \n", c);
    return c;
}

int main(int argc, char **argv) {
  char *ch = "apples";
  ch = cpy_data(ch, 6, 20);  
}

答案 1 :(得分:0)

程序几乎没有问题

1)您的while循环使您的memcpy可以访问超出您分配的内存范围的内存。因此,让您的表情看起来像while(n < out_len-rem){

2)字符串应始终以\0结尾。因此,您的memcpy应该看起来像memcpy(&c[n], ip_str, rem-1);