C++ 从文件写入字符串数组指针时出错(读访问冲突)?CPP
对于一个问题,我必须使用动态分配和函数(仅使用指针变量)从.txt文件中读取名称,并按词汇顺序对名称进行排序。然而,我甚至不能让read函数正常工作。它写道:C++ 从文件写入字符串数组指针时出错(读访问冲突)?CPP,c++,arrays,function,pointers,dynamic-memory-allocation,C++,Arrays,Function,Pointers,Dynamic Memory Allocation,对于一个问题,我必须使用动态分配和函数(仅使用指针变量)从.txt文件中读取名称,并按词汇顺序对名称进行排序。然而,我甚至不能让read函数正常工作。它写道: void readNames(std::string* a[]) { std::ifstream fin; fin.open("names.txt"); for (int i = 0; i < 7; ++i) { fin >> *(a[i]);
void readNames(std::string* a[])
{
std::ifstream fin;
fin.open("names.txt");
for (int i = 0; i < 7; ++i)
{
fin >> *(a[i]);
std::cout << *a[i];
}
}
但是,当我运行此命令时,会出现以下错误:
引发异常:读取访问冲突。
这是0xCCCC
并显示此功能(不确定是否有帮助):
void\u Check\u offset(const size\u type _Off)const{//检查_Off是否在[0,size()]的范围内
如果(\u Mysize<\u Off){
_Xran();
}
}
如果有人能帮我,我将非常感激,谢谢 为了详细说明WhozCraig的评论,让我们假设如下:
驻留在堆栈上,因此我们给它地址0x7f001000名称
- 您分配的字符串数组驻留在堆上,因此我们给它地址0x1000
- 您已将该地址分配给
,因此地址0x7f001000包含值0x1000名称
readNames
中,a
是names
的地址,因此表达式*(a[i])
可以重写为:
*(*(&names + i))
对于i=0,这是可行的。基本上,您将a
解引用一次以获取数组的开头,然后再次获取对第一个分配的std::string
的引用
对于任何其他i,访问堆栈(0x7f001000+i)上的数据,然后将该值作为指向std::字符串的指针取消引用
通过编写(*a)[i]
可以得到以下计算结果:
*(*(&names) + i)
那是
*(names + i)
,或
为了详细说明WhozCraig的评论,让我们假设如下:
驻留在堆栈上,因此我们给它地址0x7f001000名称
- 您分配的字符串数组驻留在堆上,因此我们给它地址0x1000
- 您已将该地址分配给
,因此地址0x7f001000包含值0x1000名称
readNames
中,a
是names
的地址,因此表达式*(a[i])
可以重写为:
*(*(&names + i))
对于i=0,这是可行的。基本上,您将a
解引用一次以获取数组的开头,然后再次获取对第一个分配的std::string
的引用
对于任何其他i,访问堆栈(0x7f001000+i)上的数据,然后将该值作为指向std::字符串的指针取消引用
通过编写(*a)[i]
可以得到以下计算结果:
*(*(&names) + i)
那是
*(names + i)
,或
(*a)[i]
在readNames
中的所有上下文中都可以执行您想要的操作,但是按地址传递名称仍然有一种非常糟糕的代码味道。首先,我认为没有理由按地址传递指针,除非API本身是固定的(而且它看起来肯定不像),坦率地说,我会更改调用方和函数,或者更好,改为使用字符串向量。0xCCCC
表示未初始化堆栈内存:我这样做的唯一原因是因为我认为这就是问题所要求的。我在原来的问题中包括了硬件问题。void readNames(std::string*a[])
最好写为void readNames(std::array&arr)
或者std::array readNames()
我想老师希望你使用void readNames(std::string*arr,int numElements)
而不是void readNames(std::string*a[])
(*a)[i]
在readNames
的所有上下文中都可以执行您想要的操作,但是按地址传递名称仍然有一种非常糟糕的代码味道。首先,我认为没有理由按地址传递指针,除非API本身是固定的(而且它看起来肯定不像),坦率地说,我会更改调用方和函数,或者更好,改为使用字符串向量。0xCCCC
表示未初始化堆栈内存:我这样做的唯一原因是因为我认为这就是问题所要求的。我在原来的问题中包括了硬件问题。void readNames(std::string*a[])
最好写为void readNames(std::array&arr)
或者std::array readNames()
我想老师希望你使用void readNames(std::string*arr,int numElements)
而不是void readNames(std::string*a[])
谢谢您的评论,我非常感谢。我试图将其更改为(*a)[I],但仍然会得到相同的错误unfortunately@ZachSal他们两个?正如我在评论中所说,在这个过程中有两个a[I]
的实例是错误的<代码>财务>>*(a[i])代码>应该是fin>>(*a)[i]代码>和std::cout是的,我把它们都改了。但是,将函数声明更改为void readnames(std::string*s),然后将fin>>s[i]更改为void readnames(std::string*s)是有效的。谢谢您的评论,我非常感谢。我试图将其更改为(*a)[I],但仍然会得到相同的错误unfortunately@ZachSal他们两个?正如我在评论中所说,在这个过程中有两个a[I]
的实例是错误的<代码>财务>>*(a[i])代码>应该是fin>>(*a)[i]代码>和std::cout是的,我把它们都改了。但是,将函数声明更改为void readnames(std::string*s),然后更改为fin>>s[i]起作用。