Getting size of a pointer after memory allocation - objective-c

I've been reading about sizeof, malloc, and malloc_size, but for some reason I cannot get it to work properly in objective c.
What I'm trying to do is to dynamically allocate memory and then check the size of the pointer.
I tried doing this:
void *pointer = malloc( sizeof(void) * 8 );
long test1 = malloc_size(pointer); // Its value is 16
long test2 = sizeof(pointer); // Its value is 8
The link below answer exactly the same question but it doesn't work for me.
EDIT:
I also tried using
char *malloc( sizeof(char) * 8)
but it didn't work either.

malloc_size is returning the correct answer - malloc returns a block of at least the size you request, but it may be (a little) larger. This is just a facet of the way dynamic memory is managed, it parallels the way disk files are made up of allocation blocks. A quick test on 64-bit Intel suggests malloc's allocation unit is probably 16 bytes.

pointer is of type of *, so no matter what memory is malloced to pointer, sizeof(pointer) should be fixed value, it's 4 (32bit sys) or 8 (64bit sys).

Related

Expanding an array within a structure in C

I've got a question about what I think boils down to C syntax and memory considerations. I have a callback in an Objective-C class that processes some audio, and one of the arguments is bufferListInOut. It represents a mono audio signal that I'd like to convert to stereo. Here's my code:
static void tap_ProcessCallback(MTAudioProcessingTapRef tap,
CMItemCount numberFrames,
MTAudioProcessingTapFlags flags,
AudioBufferList *bufferListInOut,
CMItemCount *numberFramesOut,
MTAudioProcessingTapFlags *flagsOut){
// Retrieve mono audio data into bufferListInOut
MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, NULL, NULL, NULL);
// Copy the mono channel's data
float *channelLeft = malloc(numberFrames * sizeof(float));
channelLeft = bufferListInOut->mBuffers[0].mData;
// Attempt to create a second channel which is (currently) a copy of the first
bufferListInOut->mNumberBuffers = 2; // 2 for stereo, 1 for mono
bufferListInOut->mBuffers[1].mNumberChannels = 1;
bufferListInOut->mBuffers[1].mDataByteSize = numberFrames * sizeof(Float32);
bufferListInOut->mBuffers[1].mData = channelLeft;
// Set number of frames out
*numberFramesOut = numberFrames;
}
Some notes:
In this code, the new channel is just a copy of the original, but in practice it will undergo some processing.
The naming is a little weird, but mNumberBuffers is indeed meant to be 2 and mNumberChannels is meant to be 1.
This crashes with an EXC_BAD_ACCESS error on a rendering thread down the line. So, my question is what is the right way to add a new buffer to this struct? I don't delve into C too often, so I'm sure I'm missing some basics here. Any pointers on this would be great. Thanks for reading.
You cannot do what you are attempting, at least in the way you are trying to do it. The type AudioBufferList is declared as:
struct AudioBufferList { UInt32 mNumberBuffers; AudioBuffer mBuffers[1]; };
This is a classic C pattern for a variable sized struct. To create a struct for N buffers a single block of memory is allocated with the size:
sizeof(UInt32) + N * sizeof(AudioBuffer)
The address of that block is assigned to a AudioBufferList * variable and the field mNumberBuffers set to N. You cannot simply increase the mNumberBuffers to increase the size of the array, instead you must either allocate a new complete struct, or realloc the existing one - realloc increases the size of memory block if possible or allocates a new one and copies the existing data into it if not.
Given your tap_ProcessCallback() function is passed a AudioBuuferList * value and does not return one, there is no way it can change the size of the struct (i.e. the number of buffers) it is passed.
As pointed out in comments you are also doing pointer assignment when you intend to copy memory - see memcpy and friends.
So you need a redesign - your goal is possible, just not how and where you've attempted it.
HTH

What is the meaning of "float *newAudio"

Sorry for my newbie question. Please refrain from down voting me because I am learning C. I am an experienced programmer on other languages, but not on C. I am trying to learn C at the same time I am trying to understand a library for iOS called Novaine, on Github.
This library has a module with the following signature:
Novocaine *audioManager = [Novocaine audioManager];
[audioManager setInputBlock:^(float *newAudio, UInt32 numSamples, UInt32 numChannels) {
}];
So, the internal block is receiving numSamples, numChannels and newAudio and newAudio is of kind float pointer?
What kind of object is this? an array of floats? if this is an array, how do I access its values? How do I know the number of elements it has?
This is a pointer to float value. Nothing strange here. It is often use to point some area in memory. You don't know the size of this are. Might be a single float but also can be larger, continuous space in memory.
You don't know what type of object is stored there. float doesn't mean that floats are stored there. It could be declared as void * as well. Again, it is just a space in memory. By typing float * you just give the compile a hint that when you move newAudio pointer (doing or example newAudio ++) it will move a pointer by a sizeof(float) number of bytes.
Based on method fingerprint I assume that this is a pointer to the first element of some buffer which size is probably numSamples * numChannels * size of single sample
This part of memory should be allocated first, to make sure that it's reserved for you:
float *newAudio = calloc(numSamples * numChannels, sizeof(float));

Can't malloc correctly in Objective-C/C

I have an OpenGL program, but can't alloc correctly.
m_VertexData = (GLfloat*)malloc(sizeof(m_TempVertexData));
m_NormalData = (GLfloat*)malloc(sizeof(m_TempNormalData));
NSLog(#"sizeOfTempVertex: %d sizeOfTempNormal: %d", sizeof(m_TempVertexData),sizeof(m_TempNormalData));
NSLog(#"sizeOfVertex: %d sizeOfNormal: %d",sizeof(m_VertexData),sizeof(m_NormalData));
NSLog:
sizeOfTempVertex: 432 sizeOfTempNormal: 432
sizeOfVertex: 4 sizeOfNormal: 4
sizeof tells you the size of the type (calculated at compile-time). It tells you nothing about how much memory was allocated dynamically.1
1. Except in the special case of C99's variable-length arrays.
m_VertexData and m_normalData are pointers, so their size is sizeof (whatever type it has *), so it allocates the correct amount of memory. You need to allocate sizeof(member of the array) * number of items bytes of memory. By the way, a few things related to malloc:
Don't cast the return value of malloc. It makes code unreadable and it's unnecessary as void * is implicitly promoted to whatever pointer type it is assigned to.
Don't use sizeof(type), rather sizeof(variable). If you ever change the type of the variable, it's gonna cause hard-to-track-down errors.
Considering these points, use the following code:
m_VertexData = malloc(sizeof(*m_VertexData) * numberOfItems);
According to the C standard, Section 6.5.3.4.2:
The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. The size is determined from the type of
the operand. The result is an integer. If the type of the operand is a variable length array
type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.
In your case, the operands m_VertexData and m_NormalData are pointers (which makes sense, because you have just assigned to them the result of calling malloc). Therefore, their size is the same as the size of any other pointer on your system - 4 bytes.
In case you are wondering, there is no standard way to determine how much memory you have malloc-ed; if you need that size for future reference, you need to store that number in a separate variable.
sizeof may not work how you think it works. sizeOfVertex and sizeOfNormal are both 32-bit pointers, so 4 is the correct size for both of them. There's no portable way to determine the actual size of the allocated memory; see determine size of dynamically allocated memory in c.

Struct Pointer Not Providing the Correct Size in sizeof() method

I'm having a issue getting the size of a struct pointer after allocating the memory using malloc or realloc. I've worked around this by keeping track of the memory in a separate counter, but I would like to know if this is a bug or if there is a way to properly query the size of a struct pointer.
Sample code demonstrates that no matter how much memory I allocate to the struct pointer it always returns 4 when querying using the sizeof() method.
typedef struct {
int modelID;
int bufferPosition;
int bufferSize;
} Model;
Model *models = malloc(10000 * sizeof(Model));
NSLog(#"sizeof(models) = %lu", sizeof(models)); //this prints: sizeof(models) = 4
4 is the correct answer, because "models" is a pointer, and pointers are 4 bytes. You will not be able to find the length of an array this way. Any reason you're not using NSArray?
If I understand you correctly you want to get at the size of the allocated buffer.
sizeof if the wrong way to go since it is evaluated at compile time. The size of the buffer is a runtime concept.
You would need a way to query you C library to return the allocation size for the pointer to the buffer.
Some systems have a way to get that kind of information, for instance malloc_size on Mac OS.
4 is the correct answer.
Pointers point to a memory location which could contain anything. When you are querying the size of a pointer, it gives the size of the memory location which holds the pointer, which in your case is 4.
For example
int *a = pointing to some large number;
int *b = pointing to a single digit number;
In the above case, both a and b have the same size irrespective of where they are pointing to.
For more information, have a look at this post size of a pointer
sizeof(myvar) will return size of pointer. in 32bit environment it equals to 4(bytes).
why don't you use sizeof (Model) instead?

memset error in iPad app

Hi Im currently building an iPad app. I was using the memset() as below but every tine it runs I get a bad access error?
arrayPointer = malloc(sizeof(int) * size);
memset(arrayPointer, 0, sizeof(int)* size); //sets all the values in the array to 0
Cheers
You could use calloc() it basically does the same as malloc() but also sets all bits to 0 in the allocated memory. It is also suited well for array initializations. For your example:
arrayPointer = calloc(sizeof(int), size);
EDIT: You should consider inspecting the returned pointer. NULL will be returned, when your memory allocation was erroneous.