calloc struct in C - objective-c

I'm trying to initialize a pointer to a struct with 0.0 values in there. Look at the following situation:
typedef struct
{
float a;
float b;
float c;
} structA;
structA *ptr = calloc(100000, sizeof(structA));
I want all the values in *ptr be structA with initial values of {0.0, 0.0, 0.0}, but this is not I have now. Many of the indices of *ptr appear correctly, but some indices appear with weird values (like {0.0, 0.0, 10241256124.0}).
If I try malloc, the same thing happens.
What should I do?

You're doing something wrong... I've never used objective-c, so I stuck the code below into ideone.com and it worked as expected... (printing out done, not failed because) all values were zero'd. My guess is you're not checking properly, since it's quite unlikely there's a bug in your compiler...
#include <malloc.h>
typedef struct
{
float a;
float b;
float c;
} structA;
int main() {
int count = 100000;
int i;
structA *ptr = calloc(count, sizeof(structA));
if(ptr) {
for(i=0;i<count;i++) {
if(ptr[i].a || ptr[i].b || ptr[i].c) {
printf("fail\n");
}
}
printf("done\n");
}
return 0;
}

Related

Given coordinates of two rectangles, find out if the rectangles overlap or not

I'm having a problem with completing this code. I'm not sure how to implement 'struct' in here for the rectangle points p1.x, p2.x and p1.y, and p2.y. How would I continue to go about this problem?
Should I use CGPoint?
struct coordinates
{
int x, y;
};
BOOL rectOverlap (int p1, int p2, int q1, int q2)
// getting error: "member reference base type 'int' is not a structure or union"
// on the "if" statement.
{
if (p1.x > q2.x || q2.x > p1.x || p1.y < q2.y || q2.y < p1.y) { //this line error
return false;
} else {
return true;
}
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
//nothing here yet.
}
return 0;
}
In objc there is a struct to define a rectangle called CGRect.
You can create one with the method CGRectMake
Then you should use the method CGRectIntersectsRect which determines if two CGRect overlap or not. Its documentation is here

scanf function in objective-c, float and double

I just a beginner in objective-C.
Below is a calculator of temperature.
I find a solution on the internet. The problem is the scanf.
At first, I set the f as a double, but program has problem.
So I change it to float.
May I ask what's going on on scanf function in objective-c?
Only can set character, int and float?
Another question is, what if I want to set a double, to use in another function which only accept double variable?
Thanks
import
int main(int argc, const char * argv[])
{
#autoreleasepool {
double c;
float f;
NSLog(#"Please enter F temp");
scanf("%f", &f);
c = (f-32) / 1.8;
//c = 1.3E-3;
// insert code here...
NSLog(#"The C temp is %.3f", c);
}
return 0;
}
Use %f for float and %lf for double. However be sure to check the return value from scanf() (or sscanf()) to ensure it parsed the correct number of values:
double d;
printf("Entry thy number mortal: ");
if (scanf("%lf", &d)) == 1) {
printf("Oh that's nice, you entered %f\n", d);
}

Convert GLfloat [] array to GLfloat * array

Is there a quicker way to convert the following data into a c style pointer array?
GLfloat verticalLines [] = {
0.59, 0.66, 0.0,
0.59, -0.14, 0.0
}
My current approach is to manually iterate over the data using the method below:
-(GLfloat *)updateLineVertices{
int totalVertices = 6;
GLfloat *lineVertices = (GLfloat *)malloc(sizeof(GLfloat) * (totalVertices));
for (int i = 0; i<totalVertices; i++) {
lineVertices[i] = verticalLines[i];
}
return lineVertices;
}
Some additional info.
Ultimately I will need the data in a format which can be easily manipulated, for example:
-(void)scaleLineAnimation{
GLfloat *lineVertices = [self updateLineVertices];
for (int i = 0; i<totalVertices; i+=3) {
lineVertices[i+1] += 0.5; //scale y axis
}
}
It depends on if verticalLines is going to stick around or not. If it's defined like it is above and it's not going to change, you can forgo the whole malloc and just point lineVertices to it.
linesVertices = &verticalLines[0]
if verticalLines is going to change, you probably want your own copy, so you've got no choice but to copy the actual data from one part of memory to another as you are doing, that being said, this might be a bit more elegant
for (int i = 0; i<totalVertices; i++){
lineVertices[i] = verticalLines[i];
}
or the preferred method is probably to use memcopy(), here is some working code
//MemcopyTest.c
#include <cstdlib>
#include <stdio.h>
#include <string.h>
int main(){
float a[] = {1.0,2.0,3.0}; //Original Array
int size = sizeof(float)*3;
float *b = (float*)malloc(size); //Allocate New Array
memcpy(b, a, size); //Copy Data
for(int i = 0; i<3; i++){
printf("%f\n", b[i]);
}
free(b);
}
What's wrong with just using verticalLines directly? Anything of type T ident[n] can be implicitly converted to T* ident as if you had written &ident[0]. And if you really want to be explicit, you can just write &ident[0] directly.

A pointer to pointer in a struct C/ObjC

typedef struct {
float Position[3];
float Color[4];
float VertexNormal[3];
} Vertex;
typedef struct WingedEdge{
struct WingedEdge* sym;
struct WingedEdge* next;
struct WingedEdge* prev;
Vertex** vertex;
GLushort** indexPointer;
} WingedEdge;
Vertex* vertices;
GLushort* indices;
struct WingedEdge* wingedEdges;
int numberOfVertices; //initialized elsewhere
int numberOfIndices; //initialized elsewhere,this is multiplied by three since I am not using a struct for the indices
vertices = (Vertex *) malloc(numberOfVertices * sizeof(Vertex));
indices = (GLushort *) malloc(numberOfIndices * sizeof(GLushort) * 3);
wingedEdges = (struct WingedEdge*)malloc(sizeof(struct WingedEdge)*numberOfIndices*3);
for (int i = 0; i < numberOfIndices*3; i+=3) {
wingedEdges[i].indexPointer = (&indices+i);
wingedEdges[i+1].indexPointer = (&indices+i);
wingedEdges[i+2].indexPointer = (&indices+i);
wingedEdges[i].vertex = (&vertices+indices[i]);
wingedEdges[i+1].vertex = (&vertices+indices[i+1]);
wingedEdges[i+2].vertex = (&vertices+indices[i+2]);
NSLog(#"%hu %hu %hu", *(indices+i),*(indices+i+1),indices[i+2]);
NSLog(#"%f %f %f", (vertices+indices[i])->Position[0], (vertices+indices[i])->Position[1], (vertices+indices[i])->Position[2]);
NSLog(#"%f %f %f", (vertices+indices[i+1])->Position[0], (vertices+indices[i+1])->Position[1], (vertices+indices[i+1])->Position[2]);
NSLog(#"%f %f %f", (vertices+indices[i+2])->Position[0], (vertices+indices[i+2])->Position[1], (vertices+indices[i+2])->Position[2]);
NSLog(#"%hu", **(wingedEdges[i].indexPointer));
}
Tried looking at a few other problems with pointers and structs but I did not find anything. I am getting an error with the last NSLog call. Everything thing in the NSLog calls with indices and vertices is correct so it looks like it might be a simple syntax error or pointer issue. Also, how would I increment the pointer that indexPointer points to? Since indexPointer points to a indices pointer, then I want to access indices+1 and indices+2 as well through indexPointer.
(&indices+i) doesn't point to any memory you have allocated.
What will work is to change the indexPointer and vertex to single pointers and then
wingedEdges[i].indexPointer = &indices[i];
wingedEdges[i].vertex = &vertices[indices[i]];
Then *(wingedEdges[i].indexPointer) is the same as indices[i] and
wingedEdges[i].vertex->Position[0] is the same as vertices[indices[i]].Position[0]. However, you will not get the automatic updating that you want (see my comments for more details). I recommend a simple inline function:
inline *Vertex vertex(WingedEdge* e)
{
return &vertices[*(e->indexPointer)];
}

Converting int to bytes and switching endian efficiently

I have to do some int -> byte conversion and switch to big endian for some MIDI data I'm writing. Right now, I'm doing it like:
int tempo = 500000;
char* a = (char*)&tempo;
//reverse it
inverse(a, 3);
[myMutableData appendBytes:a length:3];
and the inverse function:
void inverse(char inver_a[],int j)
{
int i,temp;
j--;
for(i=0;i<(j/2);i++)
{
temp=inver_a[i];
inver_a[i]=inver_a[j];
inver_a[j]=temp;
j--;
}
}
It works, but it's not real clean, and I don't like that I'm having to specify 3 both times (since I have the luxury of knowing how many bytes it will end up).
Is there a more convenient way I should be approaching this?
Use the Core Foundation byte swapping functions.
int32_t unswapped = 0x12345678;
int32_t swapped = CFSwapInt32HostToBig(unswapped);
char* a = (char*) &swapped;
[myMutableData appendBytes:a length:sizeof(int32_t)];
This should do the trick:
/*
Quick swap of Endian.
*/
#include <stdio.h>
int main(){
unsigned int number = 0x04030201;
char *p1, *p2;
int i;
p1 = (char *) &number;
p2 = (p1 + 3);
for (i=0; i<2; i++){
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return 0;
}
You can pack it into a function in whatever way you want to use it. The bitwise swap should compile into some pretty neat assembly :)
Hope it helps :)
int tempo = 500000;
//reverse it
inverse(&tempo);
[myMutableData appendBytes:(char*)tempo length:sizeof(tempo)];
and the inverse function:
void inverse(int *value)
{
char inver_a = (char*)value;
int j = sizeof(*value); //or u can put 2
int i,temp;
// commenting this j--;
for(i=0;i<(j/2);i++)
{
temp=inver_a[i];
inver_a[i]=inver_a[j];
inver_a[j]=temp;
j--;
}
}