Is there any better way to get the memory address than this?
NSLog(#"%p", anObject);
I would rather get the plain long value.
Also you can caste some Type* to intptr_t, and look at this address in decimal representation:
NSLog(#"%lu", (uintptr_t)anObject);
To represent pointer address as integer in C exists 2 types: intptr_t and uintptr_t.
intptr_t is defined as __darwin_intptr_t.
and __darwin_intptr_t defined as long:
typedef long __darwin_intptr_t;
uintptr_t defined as unsigned long:
typedef unsigned long uintptr_t;
I think what for uintptr_t I should use %lu and for intptr_t I should use %li:
NSLog(#"%lu", (uintptr_t)anObject);
NSLog(#"%li", (intptr_t)anObject);
Related
I'm in an Objective-C method with various NSStrings that I want to pass to a C function. The C function requires a struct object be malloc'd so that it can be passed in - this struct contains char fields. So the struct is defined like this:
struct libannotate_baseManual {
char *la_bm_code; // The base code for this manual (pointer to malloc'd memory)
char *la_bm_effectiveRevisionId; // The currently effective revision ID (pointer to malloc'd memory or null if none effective)
char **la_bm_revisionId; // The null-terminated list of revision IDs in the library for this manual (pointer to malloc'd array of pointers to malloc'd memory)
};
This struct is then used in the following C function definition:
void libannotate_setManualLibrary(struct libannotate_baseManual **library) { ..
So that's the function I need to call from Objective-C.
So I have various NSStrings that I basically want to pass in there, to represent the chars - la_bm_code, la_bm_effectiveRevisionId, la_bm_revision. I could convert those to const chars by using [NSString UTF8String], but I need chars, not const chars.
Also I need to do suitable malloc's for these fields, though apparently I don't need to worry about freeing the memory afterwards. C is not my strong point, though I know Objective-C well.
strdup() is your friend here as that both malloc()s and strcpy()s for you in one simple step. It's memory is also released using free() and it does your const char * to char * conversion for you!
NSString *code = ..., *effectiveRevId = ..., *revId = ...;
struct libannotate_baseManual *abm = malloc(sizeof(struct libannotate_baseManual));
abm->la_bm_code = strdup([code UTF8String]);
abm->la_bm_effectiveRevisionId = strdup([effectiveRevId UTF8String]);
const unsigned numRevIds = 1;
abm->la_bm_effectiveRevisionId = malloc(sizeof(char *) * (numRevIds + 1));
abm->la_bm_effectiveRevisionId[0] = strdup([revId UTF8String]);
abm->la_bm_effectiveRevisionId[1] = NULL;
const unsigned numAbms = 1;
struct libannotate_baseManual **abms = malloc(sizeof(struct libannotate_baseManual *) * (numAbms + 1));
abms[0] = abm;
abms[1] = NULL;
libannotate_setManualLibrary(abms);
Good luck, you'll need it. It's one of the worst interfaces I've ever seen.
I am looking for an effective way to save NSDecimalNumber with other data in NSData buffer.
I have not found a method to do it directly from NSDecimalNumber.
However, it is easy to convert it with :
NSDecimal value = [theDecimalNumber decimalValue];
And it is not difficult to transfer NSDecimal in memory (20 bytes).
But, my question: The NSDecimalNumber and NSDecimal values are they exactly the same?
Because their declarations have some differences (ExternalRefCount ?):
#interface NSDecimalNumber : NSNumber {
#private
signed int _exponent:8;
unsigned int _length:4;
unsigned int _isNegative:1;
unsigned int _isCompact:1;
unsigned int _reserved:1;
unsigned int _hasExternalRefCount:1;
unsigned int _refs:16;
unsigned short _mantissa[0]; /* GCC */
}
typedef struct {
signed int _exponent:8;
unsigned int _length:4; // length == 0 && isNegative -> NaN
unsigned int _isNegative:1;
unsigned int _isCompact:1;
unsigned int _reserved:18;
unsigned short _mantissa[NSDecimalMaxSize];
} NSDecimal;
Is it possible to perform many transfers between the two type, without any loss of precision ?
Did you try to use NSArchiver class methods?
NSData *data=[NSArchiver archivedDataWithRootObject:yourNumber];
I made numerous calculations with the transfer from one to the other without any problems.
So I think we can say that they are suitable as identical.
I extend NSDecimalNumber with :
#define DecNum_SizeOf 20
+ (NSDecimalNumber *) fromPtr:(void *)ptr
{
NSDecimal valueRead;
memcpy (&valueRead, ptr, DecNum_SizeOf);
return [NSDecimalNumber decimalNumberWithDecimal:valueRead];
}
- (void) toPtr:(void *)ptr
{
NSDecimal valueWrite = [self decimalValue];
memcpy (ptr, &valueWrite, DecNum_SizeOf);
}
While awaiting a method more "standard" to perform the job as well
NSString *lang = #"en";
const char* ar = [lang UTF8String];
int size_of_array = (sizeof ar) / (sizeof ar[0]);
size_of_array is equal to 4 and (sizeof ar) = 4 and sizeof ar[0] = 1.
Why? I think it (size_of_array) has to be 2.
sizeof ar will get the size of the type char *, which is a pointer and so takes 4 bytes in memory. You want to get the length of the string, so use the function strlen instead of sizeof ar
It isn't clear what you are trying to do.
Your third line of code references an array "ar" that isn't declared anywhere in your post, and doesn't seem to relate to the code before it.
Also, the bit sizeof ar[] doesn't make much sense. That will give you the size of a single element in your ar array, whatever that is. So you are taking the size of the pointer variable ar, and dividing it by the size of one element in the ar array.
Are you trying to determine the memory size of the ASCII string lang_ch?
If so, then you want
int size_of_array = strlen(lang_ch) + 1;
That will give you the length of the string you get back, including the null terminator.
I got a suspicious pointer conversion error here. What might be the reason of this error?
I also initialized the code[] array globally as int *code[128]={0};
void encode(const char *s, int *out)
{
while(*s)
{
out=code[*s];
out+=strlen(code[*s++]); //this is where i got the error.
}
}
When you will assign a particular type pointer variable with address of different type, such type of automatic type conversion is known as suspicious type conversion.
strlen requires const char *, while int *code[128] means code is an array of int *, so code[*s++] is a int *.
When int * is supplied to const char *, you get this error.
Generally supply int * pointer to strlen isn't a good idea because strlen will end when a byte is '\0'. You have a good chance to have 0 in a 4 bytes int. E.g., an integer 3 will have 3 bytes of 0, and 1 byte of 3.
In UITableView.h, in the interface declaration for UITableView, there is an ivar struct _tableFlags. The struct's members are all defined as unsigned int, however the title of each member is followed by a colon and then a number.
struct {
unsigned int dataSourceNumberOfRowsInSection:1;
unsigned int dataSourceCellForRow:1;
…
unsigned int longPressAutoscrollingActive:1;
unsigned int adjustsRowHeightsForSectionLocation:1;
unsigned int customSectionContentInsetSet:1;
} _tableFlags;
Cocoa tends to make common use of this syntax in its header files, but I've no clue what it means and what its function is. What does the colon and the number following the member title mean?
These are bit fields. The number after the colon is the number of bits the variable takes in the structure.
See also: how to declare an unsigned int in a C program