【问题标题】:What is proper way to copy this vector char array into a String将此向量字符数组复制到字符串中的正确方法是什么
【发布时间】:2018-06-25 10:02:53
【问题描述】:

我正在尝试使用一个 C API,它返回一个 void**(一个数据数组的数组),它可能包含任意数量的每种不同类型(double、long、short、custom struct ...)对除了数组 char 数组之外的所有内容都适用。

// a simplified API prototype
void READHISTORY( long id                  // ID in custom database
                , short numFields          // number of fields 
                , const timestruct* oldest // oldest time to look up
                , const timestruct* newest // newest time to look up
                , long maxRetVals          // the size of each data array
                , const short DataTypes[]  // types[] length numFields
                , void* theData[]          // pointers to data arrays
                , short* numReturned       // number of returned values 
)

要设置主读取,读取数据库以查看有多少字段及其自定义类型。

#define MAXVALS (2048) 
long id = 20L;
short vals;  // number of vals returned
tstruct oldest = {2017,1,1,0,0,0};
tstruct newest = {2018,1,1,0,0,0}; 
int numFields;
std::vector<short> datatypes;

GETFIELDS(id, &numFields, datatypes);  // API to get the number and types of fields
std::vector<void*> values;

for(int i=0; i<numFields; i++) {
    datatypes.push_back(DataTypes[i]);
    switch (DataTypes[i]) { // want the arrays created dynamically 
       case -1: // time 
          values.push_back(new tstruct[MAXVALS]);break;
       case -2: // short
          values.push_back(new short[MAXVALS]);break;                          
       case -3: // long
          values.push_back(new long[MAXVALS]);break;
       case -4: // double
          values.push_back(new double[MAXVALS]);break;
       default: // positive numbers are char array length
          values.push_back(new char[DataTypes[i]][MAXVALS]);
    }
}

READHISTORY 调用正在运行并返回数据,但是我收到 char 数组数组的异常错误。

// call the API to get data into the individual data arrays
READHISTORY(id, numFields, &oldest, &newest, MAXVALS, datatypes.data(), values.data(), &vals);

for (int i=0; i<vals ; i++) {
  for(int j=0; j< datatypes.size(); j++) {
    switch(datatypes[j]) {
      case -1: tstruct tval = static_cast<tstruct*>(values[1])[i];   break; // works fine           
      case -2: short sval = static_cast<short*>(values[j])[i];       break; // works fine
      case -3: long lval = static_cast<long*>(values[j])[i];         break; // works fine
      case -4: double dval = static_cast<double*>(values[j])[i];     break; // works fine
      ... 

      default:  
        int len = datatypes[j]; // positive datatypes are the char array length
        char* nchar = new char[len+1];

        // attempting to copy the char gets an access violation is here.
        strncpy(nchar, static_cast<char**>(values[j])[i], len); 

        nchar[len+1] = '\0';
        String^ nstr = gcnew String(nchar);
        delete nchar;
        // do something with nstr and so on... 
      }
   }
}

未处理的异常:System.AccessViolationException:试图读取或写入受保护的内存。

我做错了什么?

【问题讨论】:

  • 对于任何类型TT* 分配和指向的内存必须与std::vector&lt;T&gt; 包裹的内存相同。否则不可能从std::vector&lt;T&gt; 得到T*(你可以)。如果Tvoid*,那么void**std::vector&lt;void*&gt; 必须是等价的。
  • 您的代码看起来不错(现在,经过所有这些更改)。如果有问题,那就是你没有告诉我们或没有向我们展示的东西。在第一个版本中,DataTypesnumFields 是硬编码的。在第二个中,您从 API 请求它们。你确定结果是同步的吗?
  • 谢谢@AnT。代码是正确的。其中一种数据类型出错。 arrays char 数组未正确传递。我认为是现在,但是在尝试复制它时出现异常。我会投票,但还没有声望。

标签: c++ arrays vector c++-cli void-pointers


【解决方案1】:

您使用错误的constructor 创建向量:

std::vector<short> values(numFields);

这将创建一个包含numFields 空指针的向量。您稍后会追加动态分配的数组,但空指针仍将是 READHISTORY 将尝试使用的第一个元素。

而只是默认构造空向量:

std::vector<short> values;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多