Assigning string to pointer - pointer size?

David Butler's icon

I've set up a char pointer called t_pitch as part of my object struct. In the object initialisation routine I want to write a value to it.

x->t_pitch = sysmem_newptr(3000);
post("%ld", sysmem_ptrsize(x->t_pitch));

So I'm assigning it memory and posting the new pointer size to the max window. When running, 3000 appears in the max window as expected.

x->t_pitch = "abc";
post("%ld", sysmem_ptrsize(x->t_pitch));
post("%s", x->t_pitch);

I then assign it the value of "abc", and post the pointer size again, and then the string contents of the pointer. However when running, now having written a string to this pointer, the size is posted as a very large number (something like 1142968911). The value however, is posted correctly as abc.

Any tips on what I am doing wrong here?

$Adam's icon

Hi David,

AFAIK, this is what happens. When you say

x->t_pitch = "abc";

you assign a new pointer to your t_pitch variable. What happens here is the following:

1) When you say "abs", your program allocates a new chunk of memory of 4 bytes, and fills them with the characters 'a', 'b', 'c' and 0x00.
2) When you say x->t_pitch = "abc";, you assign this newly created buffer to your pointer. Actually, you've lost any connection to your Max-assigned buffer, which will make you unable to release the priorly assigned memory.
3) When you say post("%ld", sysmem_ptrsize(x->t_pitch));, you actually try to get the size of a pointer that was not allocated by the Max API, which leads to unexpected results.
4) Finally, since your pointer is valid though, when you say post("%s", x->t_pitch);, you get the correct result.

As a rule of thumb, in C you should NEVER assign a character literal to a character buffer (there are certain exceptions, for example if your character buffer will contain a constant string and you set this character literal in the same scope as where you defined your pointer, then it is OK to use a character literal, otherwise I would avoid that). To fill a character array with content, use the strcpy or memcpy commands (both declared in strings.h).

Hope this helps,
Ádám

David Butler's icon

I think I understand. My confusion was due to a misinterpretation of my C reference book. I thought that when writing a string at a pointer, the string would be written starting at the current pointer address.

Am I correct in thinking then, that when writing a string at a pointer, the string is entered into memory at any available address, and then the pointer updated to point to the new address?

$Adam's icon

In C, when you write a string literal, the compiler translates it into a sequence of (1) allogating a temporal string buffer with the appropriate size (2) filling the temporal buffer with the content and (3) freeing the buffer when the literal is no longer in scope (that is, if you declare the literal in the global scope, it will be valid in your whole program while if you declare it in a function, it will only be valid inside the function).

As you can see, you're correct with your assumption. However, you should take into account that this way the memory allocated for your string is managed automatically, therefore you can't really rely on its validity. If you need that string for more than a couple of operations inside a function, I would strongly suggest to allocate memory for yourself and copy the content of the literal with strcpy.

Another (actually much easier) way would be to use a C++ String. For this you'll of course need to compile your code with a C++ compiler (in XCode if you modify the extension of your source file to cpp, this will be done automatically).

Hope this helps,
Ádám

Peter Castine's icon

Sorry to say this, but the above is not entirely correct.

All the C Reference manual has to say about string literals is in Section A2.6 "String Literals," which comes down to "A string literal… has type 'array of characters' and storage class static."

The key word is "static", which means that the memory location exists constantly for the entire duration of the program runtime.

Programs do not "automatically allocate memory" for string literals, certainly not in the sense of somehow magically calling malloc(). Nor is the memory "deallocated" when leaving the function. You cannot access them outside of the code block in which they are defined, but that is a different matter entirely. The latter point is C syntax.

The problem in the original code is that sysmem_ptrsize() will *only* return a valid result for a pointer that was allocated by sysmem_newptr (or sysmem_newptrclear, etc.). Its behavior when passed a memory address not allocated by a sysmem_newptr (& Co.) is undefined. The string literal "abc" was not allocated by sysmem_newptr. QED.

Frankly, you're lucky you didn't crash Max with the code.

The second problem is assuming Pascal semantics of string assignment, but that has been discussed already. If what you want is strcpy(), then use strcpy().

I dunno about C++ Strings being "easier" to use, but that's a question of taste and opinion. I find Objective-C's NSString frankly more convenient.-q

Peter Castine's icon

PS: Some quality time with , for instance the specific question at may also be helpful.

$Adam's icon

Absolutely right. I forgot to drink my wake-up coffee this morning... :-)

Roman Thilenius's icon

where do i press mouse to make hip hop.