我从朋友那里得到了这个问题
const author = {
name: req.body.name
}
AuthorModel.create(author, (error, createdAuthor)=>{
//handle error
BookModel.insertMany(req.body.books, function (err, createdbooks) {
// handle error
createdAuthor.books.push(createdbooks);
createdAuthor.save();
})
}
我的第一个观察结果是,当传递到#include <string>
#include <vector>
#include <iostream>
void riddle(std::string input)
{
auto strings = std::vector<std::string>{};
strings.push_back(input);
auto raw = strings[0].c_str();
strings.emplace_back("dummy");
std::cout << raw << "\n";
}
int main()
{
riddle("Hello world of!"); // Why does this print garbage?
//riddle("Always look at the bright side of life!"); // And why doesn't this?
std::cin.get();
}
的单词数超过3个单词时,riddle()
函数不会产生垃圾。我仍在尝试查看为什么在第一种情况下而不是第二种情况下失败。无论如何,分享这很有趣。
答案 0 :(得分:3)
这是未定义的行为(UB),表示任何事情都可能发生,包括代码正常运行。
它是UB,因为emplace_back
使向量中所有指向对象的指针无效。发生这种情况是因为可以重新分配向量(显然是这样)。
由于短字符串优化(sso),UB的第一种情况“不起作用”。由于sso,原始指针指向由向量直接分配的内存,在重新分配后会丢失。
UB的第二种情况“有效”,因为字符串文本对于SSO而言太长并且驻留在独立的存储块上。在调整大小期间,会将字符串对象从其移开,从而将文本存储块的所有权移至新创建的字符串对象。由于内存块仅更改所有权,因此它在emplace_back
之后仍然有效。
答案 1 :(得分:2)
通过进一步调用其他修改对象的成员函数,可能使返回的指针无效。
如果发生重新分配,则会修改所有包含的元素。
由于在调用$(".class").append<option value="' +value.id+','+value.emp_type+ '"' +
(+value.id+','+value.emp_type+ === lastSelectedEmpId ? 'selected="selected"' : '') +
'>' + value.emp_name + '</option>;
时无法知道是否会发生vector
重新分配,因此必须假设随后使用emplace_back
中的较早返回值会导致未定义行为。
由于未定义行为是-未定义-可能发生任何事情。因此,您的代码似乎可以正常工作或失败。两种方式都出错。