【问题标题】:Error when writing from file into pointer of string array (read access violation)? CPP从文件写入字符串数组指针时出错(读取访问冲突)? CPP
【发布时间】:2021-02-03 10:11:57
【问题描述】:

对于一个问题,我必须使用动态分配和函数(仅使用指针变量)从 .txt 文件中读取名称并按词法顺序对名称进行排序。但是,我什至无法让读取功能正常工作。它是这样写的:

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];
    }
}

我在 main 中是这样称呼它的:

std::string* names;
names = new std::string[7];
readNames(&names);

但是,当我运行它时,我得到了错误:

抛出异常:读取访问冲突。 这是 0xCCCCCCCC。

并显示此功能(不确定是否有帮助):

 void _Check_offset(const size_type _Off) const { // checks whether _Off is in the bounds of [0, size()]
        if (_Mysize < _Off) {
            _Xran();
        }
    }

如果有人能帮我解决这个问题,我将不胜感激,谢谢!

【问题讨论】:

  • (*a)[i]readNames 的所有上下文中都会做你想做的事,但是通过地址传递名称仍然有很糟糕的代码气味。我认为没有理由首先通过地址传递该指针,除非 API 本身是固定的(而且它肯定看起来不像),坦率地说,我会更改调用者和函数,或者更好的是,使用字符串向量。
  • 我这样做的唯一原因是因为我认为这就是问题所要求的。我在原始问题中包含了硬件问题。
  • void readNames(std::string* a[]) 最好写成void readNames(std::array&lt;std::string,7&gt; &amp; arr) 或者std::array&lt;std::string,7&gt; readNames()
  • 我觉得老师希望你用void readNames(std::string* arr, int numElements)而不是void readNames(std::string* a[])

标签: c++ arrays function pointers dynamic-memory-allocation


【解决方案1】:

为了详细说明 WhozCraig 的评论,我们假设如下:

  • names 驻留在栈上,所以我们给它地址 0x7f001000。
  • 你分配的字符串数组驻留在堆上,所以我们给它地址 0x1000
  • 您将该地址分配给names,因此地址 0x7f001000 包含值 0x1000。

readNames里面,a就是names的地址,所以表达式*(a[i])可以改写为:

*(*(&names + i))

对于 i=0,这是可行的。您基本上取消引用 a 一次以获得数组的开头,然后再次获得对第一个分配的 std::string 的引用。

对于任何其他 i,您访问堆栈上的数据 (0x7f001000 + i),然后将该值作为指向 std::string 的指针取消引用。

通过编写(*a)[i],您将得到以下计算:

*(*(&names) + i) 

这是

*(names + i)

,或

names[i]

【讨论】:

  • 感谢您的评论,非常感谢。我试图将其更改为 (*a)[i] ,但不幸的是我仍然遇到同样的错误
  • @ZachSal both ?正如我在评论中所说,该过程中有 两个a[i] 实例是错误的。 fin &gt;&gt; *(a[i]); 应该是 fin &gt;&gt; (*a)[i];std::cout &lt;&lt; *a[i]; 应该是 std::cout &lt;&lt; (*a)[i]; 。如果 real 代码与您在问题中发布的一样,那将解决问题。如果它与发布的不一样,我们就是在浪费时间。 Botje 的回答很好地描述了使用不正确的地址是如何出错的。
  • 是的,我两个都改了。但是将函数声明更改为 void readnames(std::string* s) 然后 fin>>s[i] 有效。
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2019-04-16
  • 2017-08-23
相关资源
最近更新 更多