我想:
您可以从here获得简化代码。
程序会产生段错误,但仅当编写器设置为二进制模式时,且仅当数据超过特定大小时才会生成。在ASCII模式下,一切都很好。
This可能是相关的。
你能证实这种行为吗?我究竟做错了什么?如果它是一个错误,我该如何解决?
非常感谢您的帮助。
编辑:我直接在这里添加示例代码(与上面给定的链接相同):
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkXMLMultiBlockDataWriter.h>
#include <vtkXMLMultiBlockDataReader.h>
#include <vtkStringArray.h>
#include <sys/stat.h>
#include <sstream>
int main(int, char *[])
{
/**
* notes:
* -> it works with ascii writer configuration (BINARY=0) for any M,N.
* -> with binary writer configuration (BINARY=1), it segfaults for higher M,N
* -> {N=100,M=1} works. {N=100,M=10} fails. {N=1000,M=1} fails.
*/
const unsigned int N = 1000; // number of points
const unsigned int M = 1; // number of characters in the string
const bool BINARY = 1; // 0=ascii, 1=binary
std::string filename = "output/test_output.vtm";
std::stringstream mystring;
struct stat buffer;
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkStringArray> stringAttribute =
vtkSmartPointer<vtkStringArray>::New();
vtkSmartPointer<vtkPolyData> mypolydata =
vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkMultiBlockDataSet> multiBDS =
vtkSmartPointer<vtkMultiBlockDataSet>::New ();
vtkSmartPointer<vtkXMLMultiBlockDataWriter> writer1 =
vtkSmartPointer<vtkXMLMultiBlockDataWriter>::New();
vtkSmartPointer<vtkMultiBlockDataSet> multiBDS_read =
vtkSmartPointer<vtkMultiBlockDataSet>::New ();
vtkSmartPointer<vtkXMLMultiBlockDataReader> reader =
vtkSmartPointer<vtkXMLMultiBlockDataReader>::New();
vtkSmartPointer<vtkXMLMultiBlockDataWriter> writer2 =
vtkSmartPointer<vtkXMLMultiBlockDataWriter>::New();
stringAttribute->SetNumberOfComponents(1);
reader->SetFileName(filename.c_str());
writer1->SetFileName(filename.c_str());
writer2->SetFileName(filename.c_str());
if (BINARY) {
writer1->SetDataModeToBinary(); //segfault
writer2->SetDataModeToBinary(); // segfault
}
else {
writer1->SetDataModeToAscii(); // works
writer2->SetDataModeToAscii(); // works
}
//create output folder and clear content:
std::string outfolder = "output/";
mkdir(outfolder.c_str(), 0777);
system("exec rm -r output/*");
// create some points:
for (int k=0; k<N; ++k) {
points->InsertNextPoint(0.0, 0.0, 0.0);
}
// create some string attributes:
for (int k=0; k<N; ++k) {
for (int i=0; i<M; ++i) {
mystring << "x";
}
stringAttribute->InsertNextValue(mystring.str().c_str());
}
// assemble and write to file:
mypolydata->SetPoints(points);
mypolydata->GetPointData()->AddArray(stringAttribute);
multiBDS->SetBlock(0,mypolydata);
writer1->SetInput(multiBDS);
writer1->Write();
//now read the file again:
if (stat (filename.c_str(), &buffer) == 0) {
reader->Update();
multiBDS_read->ShallowCopy(reader->GetOutput());
}
else {
std::cout<<"file not found."<<std::endl;
}
// assemble and write again:
//system("exec rm -r output/*"); // remove original file; not necessary
multiBDS_read->SetBlock(multiBDS->GetNumberOfBlocks(),mypolydata);
writer2->SetInput(multiBDS_read);
writer2->Write();
return EXIT_SUCCESS;
}
如果您使用cmake,请使用以下CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
PROJECT(vtk_weird_segfault)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(vtk_weird_segfault MACOSX_BUNDLE vtk_weird_segfault)
if(VTK_LIBRARIES)
target_link_libraries(vtk_weird_segfault ${VTK_LIBRARIES})
else()
target_link_libraries(vtk_weird_segfault vtkHybrid vtkWidgets)
endif()