繁体   English   中英

C访问冲突错误

[英]C Access Violation error

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

第一:

您不为dest数组分配内存:

char *strPtr = NULL;    <-- allocate memory here
// strPtr = malloc(lenght + 1); // +1 for \0 chaar
my_strcpy (strPtr, str);   

第二:

此外,在字符串复制功能中,循环应在*source为nul时运行。

while(*source){

第三:

您不必在循环结束后在dest末尾添加\\0 ,而是添加*dest = '\\0'; 在while循环后输入字符串复制代码。

第四:

当循环增加时,您将返回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);    

您要在主函数中分配内存并保持字符串复制函数简单,然后请阅读Jim Balter的答案

当我尝试修改只读的字符串文字时会发生这种情况

那只是它可能发生的许多方式之一。 另一个尝试存储到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相同的语义,请保存dest的原始值并return该值,例如,

char* retval = dest;

while ((*dest++ = *source++) != '\0')
    ;

return retval;

要么

for (char* destp = dest; (*destp++ = *source++) != '\0';)
    ;

return dest;

选择您喜欢的样式。

在调用复制函数之前,您必须为strPtr分配内存。

strPtr=malloc(sizeof(str));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM