UE4 C ++-将具有“ TArray”成员的对象按值添加到“ TArray”会导致段错误

时间:2019-02-21 16:48:59

标签: arrays c++11 unreal-engine4

我有一些代码可以在一个函数中创建字符串向量,然后将其转换为document.addEventListener("DOMContentLoaded", function(event) { //here I loop the page and if preconnect found, change the icon )}; ,将其分配给对象的成员变量,然后将该对象添加到TArray<FString>中,如下所示:

TArray

函数void MyMethod() { std::vector<std::string> vec = GetVec(); TArray<FString> arr = VecStrToTArrFStr(vec); MyObject obj; obj.value = arr; this->Objects.Add(obj); } 如下:

VecStrToTArrFStr

此行出现此问题:

inline TArray<FString> VecStrToTArrFStr(std::vector<std::string> &vec) {
  TArray<FString> arr;
  arr.SetNumUninitialized(vec.size());

  for (auto &item : vec) {
    arr.Add(FString(UTF8_TO_TCHAR(item.c_str())));
  }

  return arr;
}

由于某种原因,复制数组会引发段错误。具体来说,它提供了此调用堆栈:

  • this->Objects.Add(obj);
  • __memcpy_avx_unaligned (@7fffec5b4ea0..7fffec5b5226:173)
  • FGenericPlatformMemory::Memcpy(void*, void const*, unsigned long) (/UnrealEngine/Engine/Source/Runtime/Core/Public/GenericPlatform/GenericPlatformMemory.h:348)
  • FMemory::Memcpy(void*, void const*, unsigned long) (/UnrealEngine/Engine/Source/Runtime/Core/Public/HAL/UnrealMemory.h:124)
  • TEnableIf<TIsBitwiseConstructible<wchar_t, wchar_t>::Value, void>::Type ConstructItems<wchar_t, wchar_t>(void*, wchar_t const*, int) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Templates/MemoryOps.h:137)
  • void TArray<wchar_t, FDefaultAllocator>::CopyToEmpty<wchar_t>(wchar_t const*, int, int, int) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2508)
  • TArray<wchar_t, FDefaultAllocator>::TArray(TArray<wchar_t, FDefaultAllocator> const&) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:338)
  • FString::FString(FString const&) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/UnrealString.h:73)
  • TEnableIf<!(TIsBitwiseConstructible<FString, FString>::Value), void>::Type ConstructItems<FString, FString>(void*, FString const*, int) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Templates/MemoryOps.h:126)
  • void TArray<FString, FDefaultAllocator>::CopyToEmpty<FString>(FString const*, int, int, int) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2508)
  • TArray<FString, FDefaultAllocator>::TArray(TArray<FString, FDefaultAllocator> const&) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:338)
  • MyObject::MyObject(MyObject const&) (MyObject.h)
  • int TArray<MyObject, FDefaultAllocator>::Emplace<MyObject const&>(MyObject const&&&) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:1843)

如果我将TArray<MyObject, FDefaultAllocator>::Add(MyObject const&) (/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:1916)更改为MyObject.value类型并仅为其分配std::vector<std::string>,则一切运行都很好,但是尝试为其分配vec则会引发段错误。

可能是什么原因造成的?它与我如何创建TArray<FString>对象或我如何创建FString有关系吗? UE4是在TArray中的TArray上进行垃圾回收吗?

1 个答案:

答案 0 :(得分:1)

您已在数组中填充了垃圾FString对象;当您调用TArray::Add时,FString复制构造函数尝试对其成员执行按位复制,从而导致取消引用垃圾指针,从而导致sigsegv。

要解决,请删除对SetNumUninitialized的呼叫;它没有按照您的想法做。该调用不仅保留空间,您实际上是在数组中添加指定数量的垃圾(未初始化)FStrings,然后将“真实”垃圾放在它们的末尾。看看在调用VecStrToTArrFStr之后,数组最终处于什么状态。

https://api.unrealengine.com/INT/API/Runtime/Core/Containers/TArray/SetNumUninitialized/index.html