memcpy() and memmove() not working as expected - c

I ran into this problem while working with a struct array within a struct. I'm trying to set the entry array in the dict using memcpy. I'm getting a mixture of the expected values and some seemingly random integers as output.
Oddly enough, I tried this code with some online compilers, and it worked fine. I thought that it might have to do with overlapping memory regions, so I tried memmove() but the result was the same.
I think I might be using malloc improperly for the dict, but I'm not sure. It seems I can't use malloc for the internal array, or for the individual elements. I'd appreciate any help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int i;
} entry;
typedef struct{
entry e[10];
int i;
} dict;
dict* d;
void test(dict* di){
printf("%d\n", di->i);
int k;
for (k = 0; k < 10; k ++){
printf(("%d\n"),di->e[k].i);
}
}
int main(){
entry en[10];
d = malloc(sizeof(d));
int k;
for (k = 0; k < 10; k++){
en[k].i = k;
}
d->i = 50;
memcpy(d->e, en, 10*sizeof(entry));
test(d);
return 0;
}

d = malloc(sizeof(d));
d is a dict*; sizeof d is sizeof(dict*). Looks like you meant sizeof *d.

Related

C malloc of pointer to pointer inside function not giving correct size

So I am now rewriting my fortran code in C (to use CUDA), and apparently I do not understand how to properly use malloc and pointers. I am trying to make the main function just calls to other functions, which need to malloc arrays that will then be used inside other functions. So, I am passing pointers of pointers to them as per this post: C Programming: malloc() inside another function
But the right amount of memory is not being allocated so I get segmentation faults. Here is the code:
#include <stdio.h>
#include <stdlib.h>
//#include <cuda.h>
#include <math.h>
//#include "cublas.h"
//datatype to match FORTRAN complex type
typedef float real;
typedef struct{
int nx;
int ny;
int nz;
int sz;
int tz;
} states;
void set_SPB(real **,int,states **,states **,int **);
//void set_SPB();
int find_minimum(int a[], int n,int start);
const real hc =197.32697,pi=3.1415927;
int main(){
int nmax = 2, A = 28;
real *etemp, *fock;
int *Ndex,*lookup,*lookup_a;
states *channel,*SPB;
//!generates the single particle basis to be used
set_SPB(&etemp,nmax,&SPB,&channel,&Ndex);
free(etemp);
free(Ndex);
free(SPB);
return 0;
}
void set_SPB(real **etemp,int nmax,states **SPB,states **channel,int **Ndex){
int tot_orbs = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*4;
int D = tot_orbs/4;
int Nalpha = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*9;
real E;
*etemp = (real*)malloc(D);
*Ndex = (int*)malloc(D*3);
*SPB = (states*)malloc(tot_orbs);
printf("orbits without spin degeneracy %d \n",D);
printf("size of etemp %ld \n",sizeof(*etemp)/sizeof(*etemp[0]));
return;
int i = 0;
for(int nx =-nmax;nx<=nmax;nx++){
for(int ny =-nmax;ny<=nmax;ny++){
for(int nz =-nmax;nz<=nmax;nz++){
E = 0.5*4.0*pi*pi*(nx*nx+ny*ny+nz*nz);
//printf("%d\n",i);
*etemp[i] = E;
*Ndex[0*D+i] =nx;
*Ndex[1*D+i] = ny;
*Ndex[2*D+i] = nz;
i+=1;
}
}
}
return;
}
Also I am not sure exactly if my assignments of the arrays are correct.
Specifically the print to find the number of elements of that have been allocated always gives 2, when it should be D = 125.
I cannot believe that float and int take only 1 byte in your environment.
Multiply the size to be allocated by size of their elements.
*etemp = malloc(sizeof(**etemp) * D);
*Ndex = malloc(sizeof(**Ndex) * D*3);
*SPB = malloc(sizeof(**SPB) * tot_orbs); /* not sure because this is not used */
Note that they say you shouldn't cast the result of malloc() in C.
Also note that [] operator has higher precedence than * operator, so you have to use parentheses to use the arrays.
(*etemp)[i] = E;
(*Ndex)[0*D+i] =nx;
(*Ndex)[1*D+i] = ny;
(*Ndex)[2*D+i] = nz;

Why is the following code causing segmentation fault 11?

The following code produces segmentation fault 11 when run, I couldn't figure out why. Could anyone offer some insight? Thanks in advance.
#include <stdio.h>
int main() {
int s, e;
int i,j;
typedef struct coordinate {
int x;
int y;
} coordinate;
typedef struct cell {
int altitude;
coordinate lowest_neighbor;
int visited;
int basin;
} cell;
cell cells[1000][1000];
for (i = 0; i < 1000; i++){
for (j = 0; j < 1000; j++){
cells[i][j].altitude = 9;
}
}
printf("%d", cells[0][0].altitude);
return 0;
}
Because this:
cell cells[1000][1000];
is blowing out your stack. Assuming a four-byte int with no padding in the structures, that array takes up twenty million bytes, quite a lot for a stack.
As a quick fix (for this program anyway), try out:
static cell cells[1000][1000];
which, for many implementations, will take it off the stack.
There are downsides to this approach in general as that means there is only one copy of the array, not one per function call or thread, but that won't matter here since your program only creates it once anyway.

Beginner Here Rand in c

im a 1st grader when it comes to c and need help with storing 5 random values in an array and outputting them. Heres where am at.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
struct score_card {int A_ones; int B_twos; int C_threes; int D_fours; int E_fives; int F_sixes; int G_chance;};
int dice_rolls[5];
int randomize(void);
int value;
int main(void) {
struct score_card test;
randomize;
int i;
for(i = 0; i <= 4; i++){
printf("%d\n", dice_rolls[i]);
}
printf("\n");
return 0;
}
int randomize(void){
int i;
srand(time(0));
for(i = 0; i <= 4; i++){
value = rand() % 6 + 1;
dice_rolls[i] = value;
}
}
The output is :
6294304
6294308
6294312
6294316
6294320
the goal was to use modular division to get values from 1 -->6 and store them in the dicerolls array.
I see two immediate problems.
First. you're not terminating your random numbers with a newline. That's why they're all strung together in a big sequence. Change your output line to:
printf("%d\n", &dice_rolls[i]);
Secondly, you're not actually calling randomize. The correct way to call it is with:
randomize();
The statement randomize; is simply an expression giving you the address of the function. It's as useless in this case as the expression 42; which also does nothing. However it's valid C so the compiler doesn't necessarily complain.

Random matrix struct creation

I'm trying to make a struct that generates a random matrix and am getting "error: expected â=â, â,â, â;â, âasmâ or â_attribute_â before âmatrixâ" when compiling. How can I get this to work effectively and efficiently?
I guess expected errors usually are caused by typos but I don't see any.
I'm very new to C so pointers and malloc are quite foreign to me. I really appreciate your help.
/* It's called RandomMatrixMaker.c */
#include <stdio.h>
#include <stdlib.h>
typdef struct {
char* name;
int MID;
int MRows;
int MCols;
long[][]* MSpace;
} matrix;
matrix makeRIDMatrix(char* name, int MID, int MRows, int MCols) {
matrix m;
static int i, j, r;
m.name = name;
m.MID = MID;
m.MRows = MRows;
m.MCols = MCols;
for (i=0; i<m.MRows; i++) {
for (j=0; i<m.MCols; j++) {
r = random(101);
*(m.MSpace[i][j]) = r;
}
}
return m;
}
int main(void) {
makeRIDMatrix("test", 1, 10, 10);
return 0;
}
There is indeed a typo. You misspelled typedef:
typdef struct {
should be:
typedef struct {
EDIT:
Also, there's no reason to use static here:
static int i, j, r;
You can just get rid of the static modifier.
int i, j, r;
As another poster mentioned, there's a typo, but even with that corrected, it wouldn't compile, due to the definition of matrix.MSpace.
Let's begin in makeRIDMatrix(). You've declared an automatic (stack) variable of type "matrix". At the end of the function, you return that object. Whilst this is permissible, it's not advisable. If the struct is large, you will be copying a lot of data unnecessarily. Better to pass a pointer to a matrix into makeRIDMatrix(), and have makeRIDMatrix() fill in the contents.
The test in the inner loop is against i, but should be against j.
Next, let's look at the definition of "matrix". The definition of "MSpace" is a mess, and wouldn't even compile. Even if it did, because you haven't defined the length of a row, the compiler would not be able to calcuate the offset to any given item in the array. You want a two-dimensional array without giving the row length, but you can't do that in C. You can in other languages, but not C.
There's a lot more I could point out, but I'd be missing the real point. The real point is this:
C Is Not Java.
(It's also not one of the interpreted languages such as JavaScript, PHP, Python, Ruby and so on.)
You don't get dynamically-expanding arrays; you don't get automatic allocation of memory; you don't get garbage collection of unreferenced memory.
What you need is something more like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
char* name;
int MID;
unsigned int MRows;
unsigned int MCols;
long *MSpace;
} matrix;
void makeRIDMatrix(matrix *pmx, char* name, int MID,
unsigned int MRows, unsigned int MCols) {
int i, j;
long *MSpace = malloc(sizeof(*MSpace)*MRows*MCols);
if (MSpace == NULL) {
return;
}
pmx->name = name;
pmx->MID = MID;
pmx->MRows = MRows;
pmx->MCols = MCols;
pmx->MSpace = MSpace;
srandom((unsigned int)time(NULL));
for (i=0; i<MRows; i++) {
for (j=0; i<MCols; j++) {
long int r = random() % 101L;
*(MSpace++) = r;
}
}
}
inline long * item_addr(const matrix *pmx,
unsigned int row, unsigned int col) {
if (pmx == NULL || pmx->MSpace == NULL
|| row >= pmx->MRows || col >= pmx->MCols) {
return NULL;
}
return &(pmx->MSpace[row * pmx->MCols + col]);
}
long get_item(const matrix *pmx, unsigned int row, unsigned int col) {
long *addr = item_addr(pmx, row, col);
return addr == NULL ? 0L : *addr;
}
void set_item(matrix *pmx,
unsigned int row, unsigned int col,
long val) {
long *addr = item_addr(pmx, row, col);
if (addr != NULL) {
*addr = val;
}
}
int main(void) {
matrix m;
makeRIDMatrix(&m, "test", 1, 10, 10);
return 0;
}
Note a few things here. Firstly, for efficiency, I fill the array as if it were one-dimensional. All subsequent get/set of array items should be done through the getter/setter functions, for safety.
Secondly, a hidden nasty: makeRIDMatrix() has used malloc() to allocate the memory - but it's going to be job of the calling function (or its successors) explciitly to free() the allocated pointer when it's finished with.
Thirdly, I've changed the rows/cols variables to unsigned int - there's little sense in definining an array with negative indices!
Fourthly: little error checking. For example, makeRIDMatrix() neither knows nor cares whether the parameter values are sensible (e.g. the matrix pointer isn't checked for NULLness). That's an exercise for the student.
Fifthly, I've fixed your random number usage - after a fashion. Another exercise for the student: why is the way I did it not good practice?
However - all of this is moot. You need to get yourself a good C textbook, or a good online course, and work through the examples. The code you've given here shows that you're punching above your weight at the moment, and you need to develop some more C muscles before going into that ring!
In relation to your question about "variable sized arrays", you could have something like:
/* can stick this into your struct, this is just an example */
size_t rows, cols;
long **matrix;
/* set the values of rows, cols */
/* create the "array" of rows (array of pointers to longs) */
matrix = (long**)malloc(rows * sizeof(long*));
/* create the array of columns (array of longs at each row) */
for (i = 0; i < rows; i++)
matrix[i] = (long*)malloc(cols * sizeof(long));
/* ... */
/* free the memory at the end */
for (i = 0; i < rows; i++)
free(matrix[i]);
free(matrix);
Then you can just access the dynamically allocated matrix similar to any other array of arrays.
ie. to set element at the first row (row 0) and fourth column (column 3) to 5:
matrix[0][3] = 5;

Sorting strings with C

My aim is to write an app which generates an char - array (each should be random-filled with strings of the length 4) and sorts this array. The time this process takes should be measured. I coded the following:
#include <string.h>
#include <jni.h>
#include <time.h>
#include <math.h>
clock_t start, finish;
static int ARRAY_LENGTH = 200;
static int WORD_LENGTH = 4;
char values[200];
void sortStringArray(void){
int i, j;
for(i = 0; i < ARRAY_LENGTH; i++){
for(j = 0; j < ARRAY_LENGTH-1; j++){
if(strcmp(values[j], values[j+1]) > 0) {
char holder = values[j+1];
values[j+1] = values[j];
values[j] = holder;
}
}
}
}
char generateRandomChar(char aC[]){
int length = strlen(aC);
char randStr[WORD_LENGTH];
int m;
for(m = 0; m <WORD_LENGTH; m++){
int randNr = rand()%length;
randStr[m] = aC[randNr];
}
return randStr;
}
void fillStringArray(void)
{
char allowedChars[] = "abcdefghijklmnopqrstuvwxyz";
int k;
for(k = 0; k < ARRAY_LENGTH; k++){
char randStr = generateRandomChar(allowedChars);
values[k] = randStr;
}
}
double
Java_com_example_hellojni_HelloJni_processStringSort( JNIEnv* env, jobject thiz)
{
start = clock();
fillStringArray();
sortStringArray();
finish = clock();
return ((double)(finish - start));
}
Since I am pretty new to coding C, i am not that fimilar with the concept of pointers, and therefore i recieve some mistakes.
alt text http://img38.imageshack.us/img38/2894/androidndkdebugc.jpg
It would be helpful if sb could explain me where it would be useful to use a pointer in this code. Some help with the errors would be very appreciated.
Thanks! Ripei
Without re-writing your code from scratch, it is difficult to to know where to start. I'm afraid it is all wrong. In order to get a good understanding of pointer and character string use in C, you must read a good, authoritative book on the language, Luckily, C has one of the best such books in the world - The C Programming Language. If you haven't already got a copy, get one, and if you have, re-read the chapters on pointers and strings.
Well for one thing you seem to think that char means string.... sometimes? char means a character, a number between 0 and 255. As the warnings on line 15 say, values[j] and values[j+1] are not strings (char *), they are characters (char). You probably want to make values an array of strings, ie an array of arrays of characters.
The 2nd set of warnings you're getting are related to line 31, where you're returning an array of characters (a pointer) from a function that states that it returns a character. The compiler silently casts the pointer to a character (since a pointer is a number) and returns that. You'll end up with a random number, which is probably not what you want.
To fix this you'll have to make the function return a char *, but there's a catch. randStr is gone as soon as you get out of the function, thus making it impossible to return. You could use strdup to duplicate the string and, after you're done using it in your main function, you call free to get rid of it.
While we're on this function, the parameter to it should be a char *, not a char[]. They have different meanings.
The last message (the only error reported as such apparently) is because you didn't define rand(). Adding a #include <stdlib.h> at the beginning of the program should fix it.
Thank you very much Blindy for your hints. I tried to implement your hints. Now the program doesn't throw errors but the problem is that i can't check if the operation is done correctly with the programm-environment i've to work with. Do you think the code is correct as it is shown below? Also the time it takes is quite less: 11ms. Do I calc this right?
Neil Butterworth,... well your're probably right, but I had to start somehow... and I tried my best to do so.
Vinko Vrsalovic,... well you're not right ;) I did it step by step but I thought that its better to show you the whole program and all errors at one time.
#include <string.h>
#include <jni.h>
#include <time.h>
#include <stdlib.h>
long start, finish;
static int ARRAY_LENGTH = 500;
static int WORD_LENGTH = 4;
static int LOOPS = 10;
char *values[1000];
static long getTime(void){
struct timeval now;
gettimeofday(&now, NULL);
return (long)(now.tv_sec*1000 + now.tv_usec/1000);
}
void sortStringArray(void){
int i, j;
for(i = 0; i < ARRAY_LENGTH; i++){
for(j = 0; j < ARRAY_LENGTH-1; j++){
if(strcmp(values[j], values[j+1]) > 0) {
char *holder = values[j+1];
values[j+1] = values[j];
values[j] = holder;
}
}
}
}
char* generateRandomChar(char *aC){
int length = strlen(aC);
char randStr[WORD_LENGTH];
int m;
for(m = 0; m <WORD_LENGTH; m++){
int randNr = rand()%length;
randStr[m] = aC[randNr];
}
return strdup(randStr);
}
void fillStringArray(void)
{
char *allowedChars = "abcdefghijklmnopqrstuvwxyz";
int k;
for(k = 0; k < ARRAY_LENGTH; k++){
char *randStr = generateRandomChar(allowedChars);
values[k] = randStr;
}
}
jlong
Java_com_example_hellojni_HelloJni_processStringSort( JNIEnv* env, jobject thiz)
{
start = getTime();
int i;
for(i = 0; i < LOOPS; i++){
fillStringArray();
sortStringArray();
}
finish = getTime();
return (finish - start);
}

Resources