Visual Studio 在修改传递到函数中的指针时C++访问冲突
Visual Studio C++ access violation when modifying a pointer passed into a function
我想实现一个简单的函数,该函数获取字符串作为字符指针并在函数中修改字符串。请求的函数必须是 void,然后我必须修改传递给我的函数的主要字符串。我收到一个访问违规错误并在谷歌上搜索了它,但没有任何帮助。
我的示例代码在这里:
#include "iostream"
using namespace std;
void FindCommonStr(char*& Common,int &A)
{
int i=0;
while(1)
{
if(Common[i]==' ')
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;
}
实际上,问题发生在FindCommonStr
功能的这一部分:
for (int j=0 ; j<i-1;j++)
Common[j]='y';
如果我评论这部分,一切正常,但我无法更改字符串值。我还通过将函数定义为:
FindCommonStr(char **Common,...
不过这没有帮助,我再次收到违规错误。甚至有可能做这样的事情吗?
当你这样做时:
Common = "Hello World!";
您正在使指针Common
指向文字 C 样式字符串(并顺便泄漏您之前通过 new
分配的原始char
)。尝试修改此类文本是无效的,因此当您将其传递给FindCommonStr
并尝试修改它时,您将获得访问冲突。
您应该避免使用 C 样式字符串并使用适当的C++ std::string
- 这将节省很多问题,并且更加健壮,并且更适合C++编程。
代码的固定版本:
#include <iostream>
#include <string>
using namespace std;
static void FindCommonStr(string &Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == ' ')
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;
}
或者,如果这是一个家庭作业,由于某种深不可测的原因,您需要使用 C 字符串,那么仅使用char *
字符串的固定版本可能如下所示:
#include <iostream>
using namespace std;
static void FindCommonStr(char *Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == ' ')
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;
}
这部分在概念上是错误的:
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)
您分配变量Common
两次,因此显然,第一次赋值没有任何意义。
这就像写作:
int i = 5;
i = 6;
最重要的是,您"丢失"了分配的内存块的地址,因此您将无法在程序执行的稍后点释放它。
你似乎混淆了 char[] 和字符串
当你写的时候
char* Common = new char;
您可以在堆上为Common
指向的一个字符分配空间。
然后你写
Common = "Hello World!";
它将指针 Common 设置为指向只读内存中的字符串"Hello World"。您之前分配的堆现在已泄露。
基本上有两种方法:
要么你使用字符数组,在这种情况下,你写的东西像
char* Common = new char[strlen("Hello World!")+1];
strcpy(Common, "Hello World!");
现在 common 仍然指向堆,字符串已复制到那里。额外的 +1 字节用于保存结尾 \0 字符串终止符。
完成后,您需要释放内存公共点。
delete Common;
另一种方法是使用字符串模板
std::string Common;
这允许您分配一个字符串,它囊括了上面堆数组的所有工作。
Common = "Hello World!";
之后无需删除任何内容,因为 std::string 会为您执行此操作。
- C++尝试深度复制唯一指针时出现内存访问冲突
- 尝试通过共享指针使用变量时读取访问冲突
- 使用智能指针读取访问冲突
- C 指针转换会导致内存访问冲突
- C++:读取 Lambda 捕获的指针时出现访问冲突
- 初始化指针时出现写入访问冲突
- 不能对基于数组的指针使用数组运算符(读取访问冲突)
- C++ - 智能指针 - 访问冲突读取位置0xDDDDDDDD
- 调用指针时违反 C++ Typedef 访问冲突
- 为什么未初始化的指针会导致接近 0 的 mem 访问冲突
- 执行指针时发生C++访问冲突
- C++:使用std::ifstream读取二进制文件后删除缓冲区/指针时发生访问冲突
- 指针未指向 NULL 时的访问冲突
- 指针导致访问冲突
- 在标头中声明指针会导致访问冲突
- C++ - 函数、参数和指针 - 访问冲突
- Std::数组到指针访问冲突错误
- c++类:创建线程的对象+指向函数的指针=访问冲突
- C++指针访问冲突写入位置
- C++ shared_ptr<Base>指针访问冲突