访问冲突指针错误

Posted

技术标签:

【中文标题】访问冲突指针错误【英文标题】:Access Violation Pointer Error 【发布时间】:2016-02-15 06:27:20 【问题描述】:

我正在实现我的基本 String 类版本,但是我遇到了一个我以前从未见过的问题,并且不知道如何正确调试。我的代码粘贴在下面。所有函数都有对应的标题。我的测试只是使用 convert 构造函数创建一个对象。

A4String obj1("this");

我的问题是我得到一个访问冲突读取位置异常抛出。我的研究表明我可能试图访问 Visual Studio 分配之外的内存。我很难找到这个指针错误存在的位置。我已经在转换构造函数的每一步和随后的函数调用中放置了断点,但是我的程序在它返回到 main 之前不会抛出异常,似乎是在我的程序完全执行之后。

#include "A4String.h"



A4String::A4String() 
    data = new char[5];
    data[0] = '\0';
    capacity = 5;



A4String::~A4String() 
    if (capacity != 0)
        delete[] data;


//Copy Constructor
A4String::A4String(const A4String &right) 
    cout << "copy" << endl;

    data = new char[right.capacity + 1];
    strcpy(data, right.data, capacity);
    capacity = right.capacity;


//Convert Constructor 
A4String::A4String(const char *sptr) 
    cout << "convert" << endl;
    capacity = (strlen(sptr)) + 1;
    data = new char[capacity + 1];
    strcpy(sptr, data, capacity);


//Assignment
A4String& A4String::operator = (const A4String & right) 
    //if (capacity != 0) delete[] data;
    data = new char[right.capacity + 1];
    strcpy(data, right.data, capacity);
    capacity = right.capacity;
    return *this;

//Equivalence
bool A4String::operator == (const A4String &right) const 
    return (strcmp(data, right.data)) == 0;



int A4String::length() const 
    return capacity;


void A4String::addChar(char) 
    //Not implemented yet


string A4String::toString() 
    string str = "";
    int i = 0;
    while (data[i] != '\0') 
        str += data[i];
        i++;
    
    return str; 


void A4String::strcpy(const char *source, char* destination, int size)

    for (int i = 0; i < 20; i++)
        destination[i] = '\0';
    int  index = 0;
    while (source[index] != '\0')
        
        destination[index] = source[index];
        index++;
        
    destination[index] = '\0';




int A4String::strcmp(char *str1,  char *str2)


    if (*str1 < *str2)
        return -1;

    if (*str1 > *str2)
        return 1;

    if (*str1 == '\0')
        return 0;

    return strcmp(str1 + 1, str2 + 1);

     return 0;
     

int A4String::strlen( char *s)

    char *start;
    start = s;
    while (*s != 0)
    
        ++s;
    
    return s - start;

【问题讨论】:

调试可以尝试使用valgrind:valgrind.org. @dxiv,我有一个重载的 strcpy,我应该将它重命名为 strcpy_s。不过,它可以编译,如果您不相信我,请将其插入。 类定义和你的main是什么样的? capacity 存在不一致。在默认构造函数中,它设置为5,即分配大小,但在其他地方,它似乎设置为1,小于分配的大小。 问这样的问题,你不应该发布没有使用的代码(赋值运算符,析构函数等)将代码减少到最小,这会重现错误。另一方面,如果有一个完整的代码(头文件、主代码)会很好,因此它可以很容易地运行而无需发明这部分。 ***.com/help/mcve 【参考方案1】:

问题是你的A4String::strcpy,那行

for (int i = 0; i < 20; i++)
    destination[i] = '\0';

目的地少于 20 个字符,所以它崩溃了。

【讨论】:

【参考方案2】:

A4String::strcpy 中使用硬编码号20 是不正确的。我建议将其更改为size

void A4String::strcpy(const char *source, char* destination, int size)

    // for (int i = 0; i < 20; i++)
    for (int i = 0; i < size; i++)
        destination[i] = '\0';
    int  index = 0;

    // Add an additional check here also.
    // while (source[index] != '\0' )
    while (source[index] != '\0' && index < size)
        
        destination[index] = source[index];
        index++;
        
    destination[index] = '\0';

免责声明即使使用20 很可能会使您的程序崩溃,但修复上述功能可能无法解决您的崩溃问题。换句话说,您的代码中也可能存在其他问题。

【讨论】:

以上是关于访问冲突指针错误的主要内容,如果未能解决你的问题,请参考以下文章

访问 ccomptr 指针和应用程序崩溃时访问冲突(c 系统异常代码:c0000005)

0xC0000005:访问冲突写入位置 0xCDCCDCD 动态分配错误

访问冲突读取位置 0x00000000 cstrings

访问指向结构的指针会导致内存读取冲突

什么是分段错误?

CakePHP 语法错误或访问冲突