简体   繁体   English

修改传递给函数的指针时,Visual Studio C ++访问冲突

[英]Visual Studio C++ access violation when modifying a pointer passed into a function

I want to implement a simple function that gets a string as a char pointer and modifies the string in a function. 我想实现一个简单的函数,该函数将字符串作为char指针并修改函数中的字符串。 The requested function must be void then I have to modify the primary string passed into my function. 请求的函数必须为空,然后我必须修改传递到函数中的主字符串。 I got an access violation error and googled it but nothing helped. 我遇到访问冲突错误,并用谷歌搜索,但没有任何帮助。

My sample code is here: 我的示例代码在这里:

#include "iostream"
using namespace std;
void FindCommonStr(char*& Common,int &A)
{   
    int i=0;
    while(1)
    {
        if(Common[i]=='\0')
            break;
        i++;
    }
    cout<<"Number of Elements = "<<i<<endl;
    for (int j=0 ; j<i-1;j++)   
        Common[j]='y';      
    A=2;    
}
void main()
{
    int A=0;    
    char* Common = new char;
    Common = "Hello World!";
    cout<<"Common0 = "<< Common<<endl;
    cout<<"A0 = "<< A<<endl;
    FindCommonStr(Common,A);    
    cout<<"Common1 = "<< Common<<endl;
    cout<<"A1 = "<< A<<endl;
}

Actually the problem occured in this part of FindCommonStr funtion: 实际上,此问题发生在FindCommonStr函数的这一部分:

for (int j=0 ; j<i-1;j++)   
            Common[j]='y';

If I comment this part everything works but I cannot change the string values. 如果我对此部分进行注释,则一切正常,但无法更改字符串值。 I also tested the pointer to pointer solution by defining the function as: 我还通过将函数定义为来测试了指向指针解决方案的指针:

FindCommonStr(char **Common,...

It doesn't help though and I got the violation error again. 虽然没有帮助,但我再次收到违规错误。 Is it even possible to do such a thing? 甚至有可能这样做吗?

When you do this: 执行此操作时:

Common = "Hello World!";

you are making the pointer Common point at a literal C-style string (and incidentally leaking the original char that you allocated via new previously). 您将指针指向文字C样式的字符串的Common点(并偶然泄漏了您之前通过new分配的原始char )。 It is not valid to try to modify such a literal, so when you pass this to FindCommonStr and try to modify it you get an access violation. 尝试修改这样的文字是无效的,因此将其传递给FindCommonStr并尝试对其进行修改时,会遇到访问冲突。

You should avoid using C-style strings and use proper C++ std::string instead - this will save a lot of problems and is much more robust, as well as being more appropriate for C++ programming. 您应该避免使用C样式的字符串,而应使用正确的C ++ std::string -这将节省很多问题,并且更加健壮,并且更适合C ++编程。

Fixed version of your code: 固定版本的代码:

#include <iostream>
#include <string>

using namespace std;

static void FindCommonStr(string &Common, int &A)
{
    int i = 0;
    while (1)
    {
        if (Common[i] == '\0')
            break;
        i++;
    }
    cout << "Number of Elements = " << i << endl;
    for (int j = 0; j < i - 1; j++)
        Common[j] = 'y';
    A = 2;
}

int main()
{
    int A = 0;
    string Common = "Hello World!";
    cout << "Common0 = " << Common << endl;
    cout << "A0 = " << A << endl;
    FindCommonStr(Common, A);
    cout << "Common1 = " << Common<<endl;
    cout << "A1 = " << A << endl;
    return 0;
}

Alternatively if this is a homework assignment where you are required to use C strings for some unfathomable reason then a fixed version using only char * strings might look like this: 或者,如果这是一项家庭作业,由于某些无法理解的原因而需要使用C字符串,则仅使用char *字符串的固定版本可能如下所示:

#include <iostream>

using namespace std;

static void FindCommonStr(char *Common, int &A)
{
    int i = 0;
    while (1)
    {
        if (Common[i] == '\0')
            break;
        i++;
    }
    cout << "Number of Elements = " << i << endl;
    for (int j = 0; j < i - 1; j++)
        Common[j] = 'y';
    A = 2;
}

int main()
{
    int A = 0;
    char Common[] = "Hello World!";
    cout << "Common0 = " << Common << endl;
    cout << "A0 = " << A << endl;
    FindCommonStr(Common, A);
    cout << "Common1 = " << Common<<endl;
    cout << "A1 = " << A << endl;
    return 0;
}

This part is conceptually wrong: 这部分在概念上是错误的:

char* Common = new char;
// 'Common' is set to point to a piece of allocated memory
// (typically located in the heap)

Common = "Hello World!";
// 'Common' is set to point to a constant string
// (typically located in the code-section or in the data-section)

You are assigning variable Common twice, so obviously, the first assignment has no meaning. 您两次给变量Common赋值,所以很显然,第一次赋值没有意义。

It's like writing: 就像写:

int i = 5;
i = 6;

On top of that, you "lose" the address of the allocated memory block, so you will not be able to release it at a later point in the execution of your program. 最重要的是,您“丢失了”分配的内存块的地址,因此您将无法在程序执行的稍后时间释放它。

You seem to mixup char[] and string 您似乎混淆了char []和string

When you write 当你写

char* Common = new char; 

you allocate space on the heap for one character which Common is pointing to. 您在堆上为Common指向的一个字符分配空间。

Then you write 然后你写

Common = "Hello World!";

which sets the pointer Common to point to the string "Hello World" in read-only memory. 它将指针Common设置为指向只读存储器中的字符串“ Hello World”。 The heap you allocated previously is now leaked. 您先前分配的堆现在泄漏了。

There are basically two approaches: 基本上有两种方法:

Either you work with arrays of characters, in that case you write something like 要么使用字符数组,要么编写类似

char* Common = new char[strlen("Hello World!")+1];
strcpy(Common, "Hello World!");

Now common still points to the heap and the string has been copied there. 现在common仍然指向堆,并且字符串已复制到那里。 The extra +1 byte is to hold the ending \\0 string terminator. 额外的+1字节用于保存结尾的\\ 0字符串终止符。

You need to free the memory Common points to once you are done. 完成后,您需要释放公用点的内存。

delete Common;

The other approach is to use the string template 另一种方法是使用字符串模板

std::string Common;

this allows you to assign a string, it capsules all the work with the heap array above. 这允许您分配一个字符串,它将所有工作封装在上面的堆数组中。

Common = "Hello World!";

and there is no need to delete anything afterwards since std::string will do that for you. 而且之后无需删除任何内容,因为std :: string会为您完成此操作。

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

相关问题 尝试使用结构的双指针向客户端发送数据包时抛出访问冲突。 c ++ visual studio - Access violation thrown when trying to send packet with a double pointer of structs to client. c++ visual studio C++ 修改结构体作为指针传递给函数 - C++ Modifying struct passed to function as a pointer 执行指针时C ++访问冲突 - C++ Access Violation when executing pointer 写入 function 在 Visual Studio c++ 中引发读取访问冲突异常 - a write function throwing the exception of read access violation in visual studio c++ 访问冲突读取位置(Visual Studio C ++) - Access violation reading Location (Visual Studio C++) C ++在Visual Studio中的双向链表中读取访问冲突 - C++ Read access violation in doubly linked list in Visual Studio 引发Visual Studio C ++异常:读取访问冲突。 使用命令行参数进行调试时 - Visual Studio C++ Exception thrown: read access violation. When debugging using Command Line Argument C++ 奇怪的访问冲突 Visual Studio 2015 RC - C++ strange access violation Visual studio 2015 RC 字符串长度导致访问冲突值-Visual Studio C ++ - String length causes access violation values -Visual Studio C++ C ++类:创建Thread +指向函数= Access的指针的对象 - C++ Class: Object that creates Thread + pointer to the function = Access violation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM