I'm at my wit's end here trying to figure out what's wrong. I've had no luck with Google or Stack Overflow. Please see the code below.
Steps:
* Start with a new installation of OS X 10.9 “Mavericks.”
* Install Xcode 5.0.2 from the App Store.
* Open Xcode.
* From the menu, select File -> New -> Project.
* Select “Command Line Tool” and click Next.
* Give the project a name and click Next.
* Edit main.cpp to the code below.
* From the menu, select Project -> Scheme -> Edit Scheme.
* Add a command-line argument specifying any file on the system (such as “/Library/Scripts/VoiceOver/Time Of Day.applescript”, with quotes), and another specifying any folder, and click OK.
* From the menu, select Product -> Run.
* Authenticate to allow debugging, if necessary.
Expected results:
* The code runs without crashing, possibly reading and writing files, possibly failing.
Actual results:
* When line 33 is reached (the call to fopen with “rb”), the debugger reports EXC_BAD_ACCESS, with code=2.
This is with a brand new MacBook Pro, and a brand new installation of Xcode 5, downloaded today.
If I remove lines 51 through 68, it does NOT crash. It goes into an infinite loop then, of course, but it calls fopen multiple times with no problem, unless I give it an invalid file path, in which case the first call to fopen properly returns NULL without crashing.
What am I doing wrong here? Is this a bug in LLVM? How can I fix this?
Thanks,
Dan
P.S. Whether this code actually is correct and copies the file(s) properly is not the issue here. But I can't get past this dumb crash to debug it.
——
#include <iostream>
#include <stdio.h>
int download_multi(const char* inFilePath, const char* outFolder)
{
const size_t inBufferSize = 10000000; // about 10 MB
const size_t maxOutFileSize = 10000000000; // about 10 GB
char outFilePath[PATH_MAX];
long inFilePos = 0;
int outFileIndex = 0;
size_t totalBytesWritten = 0;
int totalBytesWrittenAllFiles = 0;
FILE* pInFile = NULL;
FILE* pOutFile = NULL;
while (true)
{
if (pInFile && feof(pInFile))
break;
if (totalBytesWritten == 0 || totalBytesWritten >= maxOutFileSize)
{
if (pInFile)
{
inFilePos = ftell(pInFile);
fclose(pInFile);
}
if (pOutFile)
fclose(pOutFile);
pInFile = fopen(inFilePath, "rb");
if (!pInFile)
{
printf("Failed to open file for read: %s\n", inFilePath);
return -2;
}
fseek(pInFile, inFilePos, SEEK_SET);
sprintf(outFilePath, "%s/part_%d.dat", outFolder, ++outFileIndex);
pOutFile = fopen(outFilePath, "wb");
if (!pOutFile)
{
printf("Failed to open file for write: %s\n", outFilePath);
return -3;
}
}
char buffer[inBufferSize];
size_t bytesRead = fread(buffer, inBufferSize, 1, pInFile);
if (ferror(pInFile))
{
printf("Error reading file: %s\n", inFilePath);
return -4;
}
size_t bytesWritten = fwrite(buffer, bytesRead, 1, pOutFile);
if (ferror(pOutFile))
{
printf("Error writing file: %s\n", outFilePath);
return -5;
}
totalBytesWritten += bytesWritten;
totalBytesWrittenAllFiles += bytesWritten;
}
if (pInFile)
fclose(pInFile);
if (pOutFile)
fclose(pOutFile);
printf("Wrote %d output file(s); %d bytes total.\n", outFileIndex, totalBytesWrittenAllFiles);
return 0;
}
int main(int argc, const char * argv[])
{
if (argc < 3)
{
printf("Please specify a file to read and a folder to write to.\n");
return -1;
}
int result = download_multi(argv[1], argv[2]);
//fcloseall();
return result;
}