2016-08-28 3 views
0

std :: vector 데이터를 NSData에 저장하고 복원 할 수 있지만 간헐적으로 작동합니다. 여기서 일 것 같았다 때문에 원래 질문을 게시하고 답을 받아 들였다 : std :: vector 데이터 저장 및 복원

Storing and Restoring std::vector from NSData

그러나, 때때로 작동하고 다른 시간

이 EXC_BAD_ACCESS 오류가 발생합니다.

http://3DTOPO.com/VectorToData.zip

는 때때로 테스트 반복 33, 47 또는 예를 들어 105에 충돌합니다 : 여기에서 다운로드 할 수있는 문제를 재현하는 예 Xcode 프로젝트를 만들었습니다. 여기

는 충돌하지 때의 역 추적입니다있는 NSData와 협력하는 것은 바람직하지만

* thread #1: tid = 0x1542ee1, 0x000000010d45e65e libsystem_platform.dylib`_platform_memmove$VARIANT$Nehalem + 254, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x7faf29000000) 
frame #0: 0x000000010d45e65e libsystem_platform.dylib`_platform_memmove$VARIANT$Nehalem + 254 
frame #1: 0x0000000109f46753 Foundation`_NSDataCreateVMDispatchData + 131 
frame #2: 0x0000000109f44cf2 Foundation`-[_NSPlaceholderData initWithBytes:length:copy:deallocator:] + 230 
frame #3: 0x0000000109f50902 Foundation`-[NSData(NSData) initWithBytes:length:] + 37 
* frame #4: 0x0000000109ea2bfe VectorToData`storeContourData() + 574 at ViewController.mm:86 
frame #5: 0x0000000109ea2943 VectorToData`-[ViewController viewDidLoad](self=0x00007faf3a10f410, _cmd="viewDidLoad") + 1443 at ViewController.mm:67 
frame #6: 0x000000010af31984 UIKit`-[UIViewController loadViewIfRequired] + 1198 
frame #7: 0x000000010af31cd3 UIKit`-[UIViewController view] + 27 
frame #8: 0x000000010ae07fb4 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 61 
frame #9: 0x000000010ae0869d UIKit`-[UIWindow _setHidden:forced:] + 282 
frame #10: 0x000000010ae1a180 UIKit`-[UIWindow makeKeyAndVisible] + 42 
frame #11: 0x000000010ad8eed9 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131 
frame #12: 0x000000010ad95568 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1769 
frame #13: 0x000000010ad92714 UIKit`-[UIApplication workspaceDidEndTransaction:] + 188 
frame #14: 0x000000010d78a8c8 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24 
frame #15: 0x000000010d78a741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178 
frame #16: 0x000000010d78aaca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45 
frame #17: 0x000000010a905301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 
frame #18: 0x000000010a8fb22c CoreFoundation`__CFRunLoopDoSources0 + 556 
frame #19: 0x000000010a8fa6e3 CoreFoundation`__CFRunLoopRun + 867 
frame #20: 0x000000010a8fa0f8 CoreFoundation`CFRunLoopRunSpecific + 488 
frame #21: 0x000000010ad91f21 UIKit`-[UIApplication _run] + 402 
frame #22: 0x000000010ad96f09 UIKit`UIApplicationMain + 171 
frame #23: 0x0000000109ea237f VectorToData`main(argc=1, argv=0x00007fff55d5d6e0) + 111 at main.m:14 
frame #24: 0x000000010d12a92d libdyld.dylib`start + 1 

것은, 나는 C++ 솔루션을 사용하고자하는 것이지만, 예 (예 : fstream 및 iostream은) 내가 발견 나는 iOS에서 일할 수 없었다. C++ 솔루션이 제시되면 데이터를 복원하고 저장하는 방법을 보여주십시오.

위에 링크 된 프로젝트를 열 수없는 경우, 여기에 관련 코드, 그냥 이름을 ViewController.mm을 삭제하고 새로운 단일보기 응용 프로그램 Xcode 프로젝트에 드롭 :

// 
// ViewController.m 
// VectorToData 
// 
// Created by jeshua on 8/27/16. 
// Copyright © 2016 3DTOPO Inc. All rights reserved. 
// 

#import "ViewController.h" 
#import <vector> 

using namespace std; 

typedef vector<CGPoint> CGContour; 
typedef vector<CGContour> CGContours; 
const size_t cgContourSize = sizeof(CGContour); 
static CGContours contoursVector; 

@interface ViewController() 

@end 

@implementation ViewController 


- (void)viewDidLoad { 
    [super viewDidLoad]; 


    for (int testNumber = 0; testNumber < 1000; testNumber++) { 

     NSLog(@"__________ Test Number: %d __________", testNumber); 

     long numberOfContours = arc4random_uniform(2000) + 1000; 

     contoursVector.clear(); 

     contoursVector = CGContours(numberOfContours); 

     long numberOfBytesGenerated = 0; 

     for(int contourNum = 0; (contourNum < numberOfContours); contourNum++) { 

      long contourPointCount = arc4random_uniform(5000) + 1; 

      CGContour thisContour = CGContour(contourPointCount); 

      for(long pointNum = 0; pointNum < thisContour.size(); pointNum++) 
      { 
       thisContour[pointNum] = CGPointMake(arc4random_uniform(800), arc4random_uniform(1200)); 
      } 

      //This might seem redundant, but in my actual code the data is converted to CGPoints here 
      //and is not already a CGPoint 
      contoursVector[contourNum] = CGContour(contourPointCount); 
      for(long pointNum = 0; pointNum < thisContour.size(); pointNum++) 
      { 
       contoursVector[contourNum][pointNum] = thisContour[pointNum]; 
       numberOfBytesGenerated += cgContourSize; 
      } 

     } 

     NSLog(@" numberContoursGenerated: %lu, numberOfBytesGenerated: %lu", numberOfContours, numberOfBytesGenerated); 

     storeContourData(); 

     NSLog(@"\n\n"); 
    } 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

void storeContourData() { 

    NSMutableArray<NSData *> *contourDataArray = [NSMutableArray new]; 

    long numberContoursStored = 0; 
    long numberOfBytesStored = 0; 

    for(const CGContour &contour : contoursVector) 
    { 

     // Both these data initializations seem to work the same 
     NSData *data = [[NSData alloc] initWithBytes:&contour[0] 
               length:contour.size() * cgContourSize]; 

//  NSData *data = [[NSData alloc] initWithBytes:contour.data() 
//           length:contour.size() * cgContourSize]; 

     [contourDataArray addObject:data]; 

     numberContoursStored++; 
     numberOfBytesStored += contour.size() * cgContourSize; 
    } 

    NSLog(@" numberContoursStored: %lu, numberOfBytesStored: %lu", numberContoursStored, numberOfBytesStored); 
} 

@end 
+0

이러한 문제를 해결하는 올바른 도구는 디버거입니다. 스택 오버플로를 묻기 전에 코드를 단계별로 실행해야합니다. 자세한 도움말은 [작은 프로그램 디버깅 방법 (Eric Lippert 작성)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)을 참조하십시오. 문제를 재현하는 [최소, 완료 및 확인 가능] (http://stackoverflow.com/help/mcve) 예제와 함께 해당 질문을 \ [편집]해야합니다. 디버거. –

+0

디버거를 밟았습니다. 위에 게시 된 백 트레이스와 충돌합니다. 또한이 문제를 나타내는 완전한 Xcode 프로젝트를 포함 시켰습니다. 단계별 문제는 간헐적 인 문제이므로 문제가 발생하기 전에 수십만 번 단계를 거쳐야 할 수 있습니다. –

+0

내 직감에서 나는 당신이 어떤 시점에서 정의되지 않은 행동을하고 있다고 생각할 것입니다. –

답변

0

문제 윤곽 바이트 크기의 잘못된 계산, 그것은

contour.size() * cgContourSize; // sizeof(vector<CGPoint>) 

아니지만해야

contour.size() * sizeof(CGPoint); 

벡터 (또는 다른 데이터 컨테이너)의 앞면 크기를 계산할 수 없습니다. 이런

문은 피해야한다 : 결과는 벡터 객체의 바이트 크기의 벡터 데이터가 아닌 바이트 크기는

sizeof(vector<...>); 

때문에.

+0

답변과 설명에 감사드립니다. –

관련 문제