我最近试图创建一个复制字符串的函数,例如: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大大大于预期的输入,并且一些尾随的垃圾数据正在打印。
答案 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);