jsd
jsd

Reputation: 7703

Ignoring parameters in C functions

I'm integrating a C library into an Objective-C app for iOS. I'm not very C-savvy... I know just enough to be dangerous.

The C function declaration is this:

extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
                         unz_file_info *pfile_info,
                         char *szFileName,
                         uLong fileNameBufferSize,
                         void *extraField,
                         uLong extraFieldBufferSize,
                         char *szComment,
                         uLong commentBufferSize));

I am really only interested in the szFileName. I know I can ignore the void* and char* by passing NULL. Can I pass some sort of NULL-equivalent to the uLong params? I'm getting a compiler warning about converting to pointer without a cast.

Here's my loop for calling this function, in case anyone wants to comment on that. Did I do the malloc/free correctly? I'm not used to the low-level C stuff. I know people complain about Objective-C reference counting but in comparison it's pretty luxurious :)

unz_file_info pfile_info;
char *szFileName = malloc(1024);
uLong fileNameBufferSize;
uLong commentBufferSize;
uLong extraFieldBufferSize;

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, fileNameBufferSize, NULL, extraFieldBufferSize, NULL, commentBufferSize);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);
free(szFileName);

Upvotes: 0

Views: 2574

Answers (5)

nos
nos

Reputation: 229058

The ulong parameters are the sizes of the buffer arguments. This is so the function knows how big those buffers are so it doesn't overflow them.

If you need the fileName argument, you must supply a correct fileNameBufferSize.

As for whether you actually can pass in a NULL pointer to the pointer arguments, only the documentation(or source code) for this function can tell you. Or if the documentation doesn't tell you, you'll have to do some basic science experiments on the function and see how it behaves.

Assuming the function accepts NULL pointers for parameters you don't want filled in, you'd likely pass 0 as the value for the ulong parameters.

You'll have to do:

unz_file_info pfile_info;
char *szFileName = malloc(1024);
uLong fileNameBufferSize = 1024;
if( szFileName == NULL) {
  //handle error
  return;
}

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, fileNameBufferSize, NULL, 0, NULL, 0);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);
free(szFileName);

You should also investigate the meaning of the return value of unzGetCurrentFileInfo. If it fails, it's unlikely you can use szFileName or any of the other arguments to the function - so don't call NSLog with those variables if the function fails

In this case, malloc seems unneccesary. Just use a local array, and drop the free() call.

char szFileName[1024];
uLong fileNameBufferSize = sizeof szFileName;

Upvotes: 1

Vinicius Kamakura
Vinicius Kamakura

Reputation: 7778

I would do something along these lines here. I removed the unused vars and instead of a malloc/free a simple allocation in the stack will do.

#define FNAME_SZ 1024 //should really read the docs on your target platform to find the proper size
unz_file_info pfile_info;
char szFileName[FNAME_SZ];

//initialize. important just to be sure
memset(szFileName, 0, FNAME_SZ);

do {
    int ret = unzGetCurrentFileInfo(zipFile, &pfile_info, szFileName, FNAME_SZ, NULL, 0, NULL, 0);
    NSLog(@"get info ret %i filename size %lu, filename %s", ret, pfile_info.size_filename, szFileName);
    // do other stuff here with the filename
}
while (unzGoToNextFile(zipFile) == UNZ_OK);

Upvotes: 0

Fred Foo
Fred Foo

Reputation: 363517

Can I pass some sort of NULL-equivalent to the uLong params? I'm getting a compiler warning about converting to pointer without a cast.

Not in general; the permitted values for parameters should be listed in the manual of the library you're embedding (zlib, by the likes of it). Don't pass NULL to a function that expects a long, that's invalid.

Worse: you are passing the values of uninitialized variables fileNameBufferSize, extraFieldBufferSize and commentBufferSize to the function. Your program has undefined behavior. Set these variables appropriately, or use literals/expressions for the arguments.

Did I do the malloc/free correctly?

You forgot to check the return value from malloc. Always check for NULL. Even better: since you're allocating a constant amount of memory, just do so on the stack:

char szFileName[1024];

No need for malloc or free. (And you might want to use PATH_MAX instead of the arbitrary 1024. What if pathnames may be longer than that on your platform?)

Edit: never mind about the PATH_MAX part; the max. length of this string should be documented in the zlib docs, since it's not the max. length of a part on your system but the max. length zlib is willing to store.

Upvotes: 6

Graeme Perrow
Graeme Perrow

Reputation: 57248

Can I pass some sort of NULL-equivalent to the uLong params?

There isn't a globally-accepted NULL for non-pointer parameters; it depends on the function. In some cases, you can pass in 0, but not always.

In this case, you're passing in the size of a buffer and supplying NULL for the buffer, so it would seem logical that passing 0 is correct.

Upvotes: 1

littleadv
littleadv

Reputation: 20262

Can I pass some sort of NULL-equivalent to the uLong params?

How about 0?

Did I do the malloc/free correctly?

Looks ok to me.

You have some other error though: fileNameBufferSize is supposed to be the size of the szFileName buffer (1024 in your code). You didn't fill it, which means it's trash, be careful with that.

edit

Yep, you should check the malloc returned value for NULL, forgot to mention that.

Upvotes: 0

Related Questions