[英]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.