简体   繁体   English

C++:旧 C 风格的字符串数组问题(如 Char**)

[英]C++: Problem with array of strings old C-style (as Char**)

Good morning friends,早上好,朋友,

I am currently working in a big chunk of code (CFD solver) as part of a collaborative development.作为协作开发的一部分,我目前正在处理大量代码(CFD 求解器)。 I am not an experienced developer and therefore the question may seem stupid, but I have come with a problem that I am unable to solve.我不是一个有经验的开发人员,因此这个问题可能看起来很愚蠢,但我遇到了一个我无法解决的问题。 I am trying to modify an array of old-style C-Strings (char**).我正在尝试修改一组旧式 C 字符串 (char**)。

In the following part I will write the important parts of the code referring to the problem.在下面的部分中,我将编写参考问题的代码的重要部分。 I can not write the whole code (since it is an enormous one (millions of lines), but it should not be a problem in understanding the underlying problem).我无法编写整个代码(因为它是一个巨大的代码(数百万行),但理解底层问题应该不是问题)。 The problem arises in the last part of the written code.问题出现在编写代码的最后一部分。

PV->noVariables and m_noSpecies are ints declared before. PV->noVariables 和 m_noSpecies 是之前声明的整数。 MInt and MChar are user defined data types. MInt 和 MChar 是用户定义的数据类型。

const MChar** m_variablesName;

(...)

m_variablesName = new const MChar*[PV->noVariables];
for(MInt i = 0; i < PV->noVariables; ++i) {
  m_variablesName[i] =  new MChar[10];
}

MInt count = 0;
m_variablesName[count] = "u";
count++;
m_variablesName[count] = "v";
count++;
if(nDim == 3) {
  m_variablesName[count] = "w";
  count++;
}
m_variablesName[count] = "rho";
count++;
m_variablesName[count] = "p";
count++;

(... some not relevant code...)

// here lies the problem 
if(m_noSpecies > 1) {
   for (MInt s = 0; s < m_noSpecies; s++){                                                                                                                                           
     m_variablesName[count] = ("Y_" + std::to_string(s)).c_str();                                                                                                                                    
     cerr << ("Y_" + std::to_string(s)).c_str() << endl;
     count++;
   }
}

// to check the values stored in m_variablesName
for (MInt n = 0; n < PV->noVariables; ++n)
    cerr << m_variablesName[n] << endl;

(... irrelevant code ...)

The output in the console is as follows:控制台中的输出如下:

First chunk of output:第一个输出块:

Y_0
Y_1
Y_2
Y_3
Y_4
Y_5
Y_6
Y_7
Y_8
Y_9
Y_10
Y_11
Y_12
Y_13
Y_14
Y_15
Y_16
Y_17

Second chunk of output:第二块输出:

u
v
rho
p
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17
Y_17

As one can notice, the Y_0 to Y_17 have all changed to Y_17, and this is not desired.可以看到,Y_0 到 Y_17 都变成了 Y_17,这是不希望的。 If I have understood the problem correctly, I think the problem lies in that the same pointer is stored in each array entry, and therefore all entries get the same values.如果我正确理解了问题,我认为问题在于每个数组条目中存储了相同的指针,因此所有条目都获得相同的值。

However, I do not know how to solve this problem.但是,我不知道如何解决这个问题。 Some help may be greatly appreciated.一些帮助可能不胜感激。 The array can not be changed to work with normal C++ strings due to compatibility reasons.由于兼容性原因,无法更改数组以使用普通 C++ 字符串。

Thank you all for your time!谢谢大家的时间!

Cherry-picking from your question, this line从你的问题中挑选樱桃,这一行

  m_variablesName[i] =  new MChar[10];

allocates space on the heap for 10 MChars and stores the pointer in m_variablesName[i] .在堆上为 10 个 MChars 分配空间并将指针存储在m_variablesName[i]

The problematic line is有问题的线路是

m_variablesName[count] = ("Y_" + std::to_string(s)).c_str();

which replaces that pointer with one to a temporary object, as "Y_" + std::to_string(s) is a temporary.它将该指针替换为指向临时对象的指针,因为"Y_" + std::to_string(s)是临时对象。

In this instance, you can use snprintf instead to write the proper characters into your first buffer:在这种情况下,您可以改用snprintf将正确的字符写入第一个缓冲区:

snprintf(m_variablesName[count], 10, "Y_%d", s);

You can also combine both steps in one with the asprintf function, which allocates and prints in one go.您还可以将这两个步骤与asprintf函数asprintf ,该函数asprintf分配打印。

All m_variablesName[count] in this snippet are allocated by此代码段中的所有m_variablesName[count]均由

for (MInt i = 0; i < PV->noVariables; ++i) {
  m_variablesName[i] =  new MChar[10];
}

These C-style strings can not be assign directly, you should use functions such as strncpy , to copy contents into:这些 C 风格的字符串不能直接赋值,你应该使用strncpy等函数将内容复制到:

for (MInt s = 0; s < m_noSpecies; s++) {
    memset(m_variablesName[count], 0, 10);
    std::string strtmp = "Y_" + std::to_string(s);
    strncpy(m_variablesName[count], strtmp.c_str(), 9);
    count++;
}

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

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