将 argv 复制到新数组中

6

以下代码引起了分段错误。请问有人能解释一下为什么吗?我想将argv的内容复制到一个新数组中,我把它称为rArray。

#include <iostream>        
using namespace std;

int main( int argc, char **argv)
{
  char **rArray;
  int numRows = argc;
  cout << "You have " << argc << " arguments:" << endl << endl;
  cout << "ARGV ARRAY" << endl;
  for (int i = 0; i < argc; i++)
  { 
    cout << argv[i] << endl;
  }
  cout << endl << endl << "COPIED ARRAY" << endl;
  for(int i; i < numRows; i++)
  {
    for (int j = 0; j < argc; j++)
      {
        rArray[i][j] = argv[i][j];
      }
  }
  for (int i = 0; i < argc; i++)
  {
    cout << "Copied array at index " << i << "is equal to " << rArray[i] << endl;;
  }
  cin.get();
}

该程序输出:
/a.out hello world
You have 3 arguments:

ARGV ARRAY
./a.out
hello
world


COPIED ARRAY
Segmentation fault: 11

为什么会出现这个错误?如何修复它?
编辑:我找到了解决方法,将char **rArray更改为string rArray,然后从那里动态分配大小。

1
char** rArray 不会为您分配任何内存,而 j < argc 也不是正确的条件。 - Ry-
@minitech 技术上说,char** rArray; 确实分配了堆栈空间(足以容纳一个指针)。 - Frerich Raabe
@FrerichRaabe:是的,我去掉了“at all”,因为那样=P - Ry-
3个回答

12

其他人指出了您的代码的各种问题;如果您确实想要复制argv,请使用std::string对象的std::vector

#include <string>
#include <vector>

int main( int argc, char **argv ) {
    std::vector<std::string> args( argv, argv + argc );
}

2
+1 - 一个更好的解决方案。如果您在注释中提到当前代码导致崩溃的问题,我会删除我的答案。 - simonc
@simonc,啊,你是指“当前代码”在问题中!好的,我一直在拼命地尝试找出C++如何在这个看似无害的答案代码中再次威胁我们所有人。 :) - Sz.

11
你需要为rArray分配内存,并且需要初始化外循环计数器i
由于argv的内容是常量字符串,因此可以只复制指向它们的指针。
rArray = new char*[argc+1];
for(int i=0; i <= argc; i++) {
    rArray[i] = argv[i];
}
// use rArray
delete [] rArray;

请注意,argv[argc]保证是NULL。我已更新循环以复制此内容(因此出现了不寻常的i<=argc退出条件)。

如果您确实想要复制字符串的内容(如minitech建议的),则代码会变得更加复杂:

rArray = new char*[argc+1];
for(int i=0; i < argc; i++) {
    int len = strlen(argv[i]) + 1;
    rArray[i] = new char[len];
    strcpy(rArray[i], argv[i]);
}
rArray[argc] = NULL;
// use rArray
for(int i=0; i < argc; i++) {
    delete [] rArray[i];
}
delete [] rArray;

2
这个不会复制字符串本身,对吧?我觉得这可能是提问者的意图。无论如何,应该是<而不是<=,对吗? - Ry-
2
是的,argv[argc]保证是NULL,但是rArray[argc]也保证越界了... - Ry-
@minitech 谢谢,那真是愚蠢!我希望现在已经纠正了。 - simonc
1
@Michele 请看第一个代码示例后面的文本。<=是有意的,它将指针复制到传递的最后一个参数(通常为NULL)。 - simonc
1
strlen(argv[i] + 1) 应该改为 strlen(argv[i]) + 1,对吗? - Grief
显示剩余6条评论

3

有一个问题是你没有对 i 进行初始化

for(int i; i < numRows; i++)
        ^-- !

第二件事是 rArray 没有被分配空间。
我建议使用 std::vector<std::string>,并将所有参数复制到向量中,您无需担心分配/释放内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接