繁体   English   中英

C ++为什么此按引用传递数组会生成运行时错误?

[英]C++ Why is this passed-by-reference array generating a runtime error?

void pushSynonyms (string synline,  char  matrizSinonimos [1024][1024]){


             stringstream synstream(synline);

             vector<int> synsAux;


             int num;

             while (synstream >> num) {synsAux.push_back(num);}


             int index=0;
             while (index<(synsAux.size()-1)){

                   int primerSinonimo=synsAux[index];
                   int segundoSinonimo=synsAux[++index];
                   matrizSinonimos[primerSinonimo][segundoSinonimo]='S';
                   matrizSinonimos [segundoSinonimo][primerSinonimo]='S';

                   }

           } 

和电话..

char matrizSinonimos[1024][1024];
     pushSynonyms("1 7", matrizSinonimos)

对于我来说,通过参考传递matrizSinonimos很重要。

编辑:从&matrizSinonimos了&。

编辑:运行时错误是:

An unhandled win32 exception occurred in program.exe [2488]![alt text][1]

它出什么问题了

您所拥有的代码-我找不到错误。 我发现的唯一问题是,如果您根本不提供任何数字,那么这部分会造成损害:

(synsAux.size()-1)

它将从0u减去1。 这将结束,因为size()返回一个无符号整数类型。 您最终将获得非常大的价值,大约2 ^ 16或2 ^ 32。 您应该将整个while条件更改为

while ((index+1) < synsAux.size())

您可以尝试在通话侧查找错误。 通常,在此之前某个地方会发生缓冲区溢出或堆损坏,结果程序在程序的稍后崩溃。

其中的参数和参数的东西

关于数组及其传递方式,我认为您可以做到。 虽然,您仍然按值传递数组。 也许您已经知道了,但我会重复一遍。 您实际上将指针传递给此数组的第一个元素:

char matrizSinonimos[1024][1024];

2d数组实际上是数组的数组。 该数组的第一个元素是数组,指向它的指针是指向数组的指针。 在这种情况下

char (*)[1024]

即使您在参数列表中说过您接受数组数组,编译器仍会像往常一样对其进行调整并使其成为指向该数组第一个元素的指针。 因此,实际上,在编译器对参数类型进行了调整之后,您的函数就具有原型:

void pushSynonyms (string synline,  char (*matrizSinonimos)[1024]);

尽管经常提出建议,但是您不能将该数组作为char**传递 ,因为被调用的函数需要内部维的大小,才能正确地以正确的偏移量解决子维。 在被调用的函数中使用char** ,然后编写类似matrizSinonimos[0][1] ,它将尝试将该数组的第一个sizeof(char **)字符解释为指针,并尝试取消引用一个随机的内存位置,如果在两次内存之间没有崩溃,则再次进行该操作。 不要那样做 您在该数组的外部尺寸中写入的大小也无关紧要。 它合理化了。 现在,通过引用传递数组并不是很重要。 但是,如果需要,您必须将整个事情更改为

void pushSynonyms (string synline,  char (&matrizSinonimos)[1024][1024]);

通过引用传递不会将指针传递给第一个元素:保留所有维度的所有大小,并且传递数组对象本身而不是值。

数组作为指针传递-无需对其进行传递引用。 如果您声明函数为:

void pushSynonyms(string synline, char matrizSinonimos[][1024]);

您对数组所做的更改将继续存在-数组不会按值传递。

异常可能是0xC00000FD ,或者是堆栈溢出!

问题在于您正在堆栈上创建一个1 MB的阵列,该阵列可能太大。

编辑1 )我忘了回答您的实际问题。 好吧:在您更正了代码以正确的方式传递数组(不再有不正确的间接寻址)之后,对我来说,您似乎最有可能没有正确检查输入内容。 您从流中读取数据,将其保存到向量中,但是从未检查过获得的所有数字是否实际上都在正确的范围内。 结束编辑1

首先 :使用原始数组可能并不是您真正想要的。 std::vectorboost::array 后者是像原始数组一样的编译时固定大小的数组,但是提供了C ++集合的type-def和方法,这对于通用(阅读:模板化)代码很实用。

而且,使用这些类可能会减少类型安全,通过引用传递,通过值传递或传递指针的混淆。

第二 :数组作为指针传递,指针本身通过值传递。

第三 :您应该在堆上分配这样的大对象。 在这种情况下,堆分配的开销微不足道,这将减少耗尽堆栈空间的机会。

第四

void someFunction(int array[10][10]);

真的是:

编辑2 )由于评论:

void someFunction(int ** array);

void someFunction(int (*array)[10]);

希望我没有在其他地方搞砸...。( 结束编辑2

类型信息将丢失为10x10数组。 为了获得您可能想要的意思,您需要编写:

void someFunction(int (&array)[10][10]);

这样,编译器可以在调用方检查该数组实际上是10x10数组。 然后,您可以像下面这样调用函数:

int main() {
  int array[10][10] = { 0 };
  someFunction(array);
  return 0;
}

尝试将其声明为:

void pushSynonyms (const string & synline,  char  *matrizSinonimos[1024] )

我相信这会做您想做的事。 正如其他人所说,您拥有它的方式会在堆栈上创建一个1MB的阵列。 另外,将synline从string更改为const string &消除了将完整的字符串副本推入堆栈的情况。

另外,我将使用某种类来封装matrizSinonimos。 就像是:

class ms
{
    char m_martix[1024][1024];
    public:
    pushSynonyms( const string & synline );
}

那么您根本不必通过它。

我不知道上面的代码有什么问题,但是如果您无法使数组语法正常工作,则可以始终这样做:

void pushSynonyms (string synline,  char  *matrizSinonimos, int rowsize, int colsize )
{
   // the code below is equivalent to 
   // char c = matrizSinonimos[a][b];
   char c = matrizSinonimos( a*rowsize + b );
   // you could also Assert( a < rowsize && b < colsize );
}

pushSynonyms( "1 7", matrizSinonimos, 1024, 1024 );

如果在编译时已知,也可以用#define SYNONYM_ARRAY_DIMENSION 1024替换rowsize和colsize,这将使乘法步骤更快。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM