当我尝试在Visual Studio中执行以下代码时,出现数据访问错误。我查了一下,但发现当我尝试修改一个只读的字符串文字时会发生这种情况。
char *my_strcpy(char *dest, const char *source)
{
int i;
while(*dest)
{
*dest++ = *source++;
}
return dest;
}
int main()
{
char str[80] = "Hello, there!";
char *strPtr = NULL;
my_strcpy (strPtr, str);
return 0;
}
error:
Unhandled exception at 0x01163C91 in PtrStrArr.exe: 0xC0000005: Access violation reading location 0x00000000.
我无法确定修改字符串文字的位置。我甚至将数组声明为常量。如果我删除声明
char *strPtr = NULL;
我收到错误
Run-Time Check Failure #3 - The variable 'strPtr' is being used without being initialized.
你能指点我的错吗?
编辑:
感谢所有答案,我能够纠正我的代码并获得如下的输出。
#include <stdio.h>
#include<malloc.h>
char *my_strcpy(char *dest, const char *source)
{
char *retVal = dest;
int i=0;
while(*source != '\0')
{
*dest++ = *source++;
}
*dest++ = '\0';
return retVal;
}
void print_array(char *str)
{
int i;
while(*str)
{
printf("%c",*str++);
}
}
int main()
{
char str[80] = "What up dude?";
char* strPtr;
strPtr = (char *)(malloc(sizeof str));
print_array (str);
printf("\n");
my_strcpy (strPtr, str);
print_array (strPtr);
return 0;
}
我确实有一个问题。在你的所有答案中,当使用malloc时,你没有从void *转换为char *。但是当我尝试出来时,我必须明确地
strPtr = (char *)(malloc(sizeof str));
我正在以正确的方式使用malloc? 感谢每一个人的答案。
答案 0 :(得分:5)
<强>首先强>
您没有为dest
数组分配内存:
char *strPtr = NULL; <-- allocate memory here
// strPtr = malloc(lenght + 1); // +1 for \0 chaar
my_strcpy (strPtr, str);
第二名:
此外,在字符串复制函数循环中,*source
为nul时应运行。
while(*source){
第三:
在循环结束后,您不要在\0
的末尾添加dest
,在字符串复制代码中的while循环后添加*dest = '\0';
。
<强>第四:强>
你在循环中返回dest
,你就增加它!
试试这段代码:
char * my_strcpy(char *dest, const char *source)
{
dest = malloc(strlen(source) + 1); //allocate memory
tdest = dest; // store it to return
while(*source) // copy until source terminate at \0
{
*tdest++ = *source++;
}
*tdest = '\0'; // add nul termination in dest string
return dest; // return allocated memory address
}
请注意,内存分配是在字符串复制功能内完成的。
顺便说一句,我没有更改你的函数原型和函数名称,但你想要构建的是strdup()
。因为内存分配是在函数内完成的,所以返回重复的字符串,所以你不需要传递第一个参数。
所以@ Jim Balter也回顾了我的答案语义正确的写函数方法是:
char * my_strdup(const char *source)
{
dest = malloc(strlen(source) + 1); //allocate memory
tdest = dest; // store it to return
while(*source) // copy until source terminate at \0
{
*tdest++ = *source++;
}
*tdest = '\0'; // add nul termination in dest string
return dest; // return allocated memory address
}
称之为:
char* strPtr = my_strdup(str);
你想要在main函数中分配内存并保持字符串复制功能简单,那么请阅读Jim Balter的answer。
答案 1 :(得分:4)
当我尝试修改一个只读的字符串文字
时会发生这种情况
这只是它可能发生的众多方式之一。另一个是试图存储到NULL
,这就是你在这里做的事情:
char str[80] = "Hello, there!";
char *strPtr = NULL;
my_strcpy (strPtr, str);
您想将str
复制到某个地方,但在哪里?您没有提供任何存储空间。
考虑
char str[80] = "Hello, there!";
char str2[sizeof str];
my_strcpy (str2, str);
或
char str[80] = "Hello, there!";
char* strptr = malloc(sizeof str);
if (!strptr)
/* do something on out-of-memory */;
my_strcpy (strptr, str);
此外,my_strcpy
正在循环,直到它在目的地中找到NUL
,这当然是错误的...你不能看到目的地,直到你那里存有东西。并且,您不是将NUL存储到目的地。考虑简单的循环
while ((*dest++ = *source++) != '\0')
;
最后,您可能不想返回dest
,现在指向NUL
。将my_strcpy
声明为return
void
并且不返回任何内容,或者如果您希望它具有与strcpy
相同的语义,请保存{{1}的原始值}和dest
,例如,
return
或
char* retval = dest;
while ((*dest++ = *source++) != '\0')
;
return retval;
选择您喜欢的风格。
答案 2 :(得分:2)
在调用复制功能之前,您必须为strPtr
分配内存
strPtr=malloc(sizeof(str));