C访问冲突错误

时间:2014-01-02 06:51:57

标签: c pointers

当我尝试在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? 感谢每一个人的答案。

3 个答案:

答案 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));