memcpy() with different data types - c

Trying to copy A into B....
char *A;
double *B;
unsigned int size = 1024;
A = malloc (size*size * sizeof (char));
B = malloc (size*size * sizeof (double));
//fill A here
memcpy (B, &A[0], (size*size * sizeof (char)));
Printing values in B don't match whats in A.
What's going wrong?
Thanks for any help!
Edit: The point of this is to test the memcpy function's speed in relation to the size of the L2 cache. I'm just wanting to make sure the code above is actually copying all of A into B. Sorry about leaving out this info: I just try to make it as simple as possible (and went too far this time)

It's hard to tell exactly what you are trying to do.
How are you printing values? Print routines like printf also depend on the type.
It sounds like you just want to get float input values. This can be done using the scanf family.
int num_floats = 10;
double* B = malloc (num_floats * sizeof (double));
int count;
for (count = 0; count < num_floats; count++)
{
printf("Insert float %d: ", count);
scanf("%f", &B[num_floats]);
}
for (count = 0; count < num_floats; count++)
{
printf("Float %d: %f", B[num_floats]);
}
free(B);
If you are trying to convert C-strings from char * to floating point numbers and don't want to use sscanf, you can also use atof.
const char* num_str = "1.01";
double num = atof(num_str);

Related

How should I make a dynamic array of 1<n<300000

I am trying to solve a problem on a competitive programming page, and it had occurred to me that a good way to solve it would be by making a dynamic array, right now I don't care about the problem and what I want to know is how something like this could be implemented.
The idea is first they give us the number of cases (the size of the array) and then we make certain tours of that array, I would also have to apply it to a matrix of characters (an array of strings), this code that I have here works well when the input of cases is 1 <n <110, but of course, when that range is passed (it should be up to 300000 ) gives me a memory access error Process finished with exit code -1073741819 (0xC0000005), which is normal considering what I'm trying to do, I don't even know if it can, thank you very much in advance!
This is my code:
int main() {
int cases, i, j, max = 0;
while ((scanf("%d", &cases)) != EOF) {
int *victims;
victims = (int *) malloc(cases * sizeof(int));
const char **date;
date = (const char **) malloc(cases * sizeof(char));
for (i = 0; i < cases; i++) {
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
}
for (i = 0; i < cases; i++) {
scanf("%s", date[i]);
scanf("%d", &victims[i]);
}
}
}
The lines
const char **date;
date = (const char **) malloc(cases * sizeof(char));
are wrong. The element is const char*, so you have to allocate for that.
In other words, you have to allocate size of a pointer, not size of a char, for each elements.
Moreover, the objects pointed at by the elements of the array date will be modified via scanf() later, so they should be char*, not const char*.
it should be
char **date;
date = malloc(cases * sizeof(char*));
or
char **date;
date = malloc(cases * sizeof(*date));
Also the line
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
is wrong. You have to allocate one more element for the terminating null-character to allow 10-character strings to be stored there.
It should be:
date[i] = malloc(11 * sizeof(char));//String max length is 10.
Also note that:
You need not multiply sizeof(char) because it is defined to be 1.
Casting the results of malloc() is considered as a bad practice.

Segmentation fault when passing 2D array to function

I'm trying to write the values from the string that is read from stdin directly into the array, but I get a segmentation fault. Being that the array is declared after I read N and M, the memory should already be allocated, right?
int main()
{
long long N;
long long M;
scanf("%lld%lld",&N,&M);
char line[M];
long long map[N][M];
for (long long i=0; i<M; i++)
{
scanf("%s", &line);
buildMap(&map, i, &line);
}
for (long long i=0; i<N; i++)
for (long long j=0; j<M; j++)
printf(&map);
}
void buildMap(long long **map, long long i, char * line)
{
for (long long j=0; j<strlen(line); j++)
{
map[i][j] = line[j]-'0';
}
I have read your codes, and I assume you are attempting to build a 2D map via user input, which is a string (named "Line" in your code) that should only contains numbers from 0 to 9. Numbers from 0 to 9 may represent different elements of the map. Am I guessing right?
I copied and modified your code, and finally I managed to get a result like this:
program screenshot
If I am guessing right, let me first explain the reasons why your code can not be successfully complied.
long long M; char line[M];
In here you have used a variable to declare the size of an array. This syntax works in some other programming languages, but not in C. In C, when compling the source code, the compiler must know exactly how much stack memory space to allocate for each function (main() function in your case). Since the complier does not know how large the array is when it is trying to complie your code, you get a compling failure.
One common solution is that, instead of storing array in stack, we choose to store array in heap, because the heap memory is dynamically allocated and released when the program is running. In other words, you can decide how much memory to allocate after you get the user input. Function malloc() and free() are used for this kind of operation.
Another problem is using "long long **map". Though it will not cause complie failure, it won't give you the expected result either. When the M (array width) of the array is a known constant value, we always perfer using "long long map[][M]" as the parameter. However, in your case, with M being unkown, the common solution is to manually calculate the target location, since the elements in an array are always stored in a linear order in memory, regardless of the array demension.
I have fixed the aforementioned two problems, and I am pasting the modified source code below, which has been successfully complied:
#include <malloc.h>
#include <string.h>
void buildMap(int *map, int i, char * line);
int main()
{
int N;
int M;
scanf("%d%d", &N, &M);
/*Since M (available memory space for "Line") is set by user, we need to build
"szSafeFormat" to restrict the user's input when typing the "Line". Assuming M
is set to 8, then "szSafeFormat" will look like "%7s". With the help of
"szSafeFormat", the scanf function will be scanf("%7s", Line), ignoring
characters after offset 7.*/
char szSafeFormat[256] = { 0 };
sprintf(szSafeFormat, "%%%ds", M - 1);
//char line[M];
char *Line = (char *)malloc(sizeof(char) * M); //raw user input
char *pszValidInput = (char *)malloc(sizeof(char) * M); //pure numbers
//long long map[N][M];
int *pnMap = (int *)malloc(sizeof(int) * M * N);
memset(pnMap, 0xFF, M * N * sizeof(int)); //initialize the Map with 0xFF
for (int i = 0; i < /*M*/N; i++)
{
scanf(szSafeFormat, Line); //get raw user input
sscanf(Line, "%[0-9]", pszValidInput); //only accept the numbers
while (getchar() != '\n'); //empty the stdin buffer
buildMap((int *)(pnMap + i * M), i, pszValidInput);
}
printf("\r\n\r\n");
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
//if the memory content is not 0xFF (means it's a valid value), then print
if (*(pnMap + i * M + j) != 0xFFFFFFFF)
{
printf("%d", *(pnMap + i * M + j));
}
}
printf("\r\n");
}
free(Line);
free(pszValidInput);
free(pnMap);
return 0;
}
void buildMap(int *map, int i, char * line)
{
for (int j = 0; j < strlen(line); j++)
{
(int) *((int *)map + j) = line[j] - '0';
}
}
I used type "int" instead of "long long", but there should not be any problems if you insist to continue using "long long". If you continue to use "long long", the condition while printing out the array values should be changed from:
if (*(pnMap + i * M + j) != 0xFFFFFFFF)
to
if (*(pnMap + i * M + j) != 0xFFFFFFFFFFFFFFFF)
There are also some other modifications regarding user input validation, with which I have written some addtional comments in the code.
Remember that C supports variable-length arrays (something which you already use). That means you can actually pass the dimensions as arguments to the function and use them in the declaration of the array argument. Perhaps something like
void buildMap(const size_t N, const size_t M, long long map[N][M], long long i, char * line) { ... }
Call like
buildMap(N, M, map, i, line);
Note that I have changed the type of N and M to size_t, which is the correct type to use for variable-length array dimensions. You should update the variable-declarations accordingly as well as use "%zu for the scanf format string.
Note that in the call to buildMap I don't use the address-of operator for the arrays. That's because arrays naturally decays to pointers to their first element. Passing e.g. &line is semantically incorrect as it would pass something of type char (*)[M] to the function, not a char *.

error: invalid operands to binary * Pointer to a pointer to a matrix

I am getting error: invalid operands to binary * on lines 13, 20, 25, 31, and 36. I'm not sure how to deal with dynamic memory allocation to a pointer to a pointer to a matrix. Also, how to store integers in a matrix like fashion with this pointer to a pointer. Also, I realize there are lots easier ways of going about this in terms of the pointers, but I have to not use any brackets and the functions inputs were supplied to me.
void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *file) {
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "\n Error: file open failed for file '%s'\n\n", file);
exit(0);
}
/* read & output m, n, p */
fscanf(fp, "%d\n%d\n%d\n", m, n, p);
printf("\n m: %d\n n: %d\n p: %d\n\n", *m, *n, *p);
/* allocate memory for A and set values to null */
A = calloc(m * n, sizeof(int));
/* read A */
int i, j;
for (i = 0; i < *m; i++) {
fscanf(fp, "\n");
for (j = 0; j < *n; j++) {
fscanf(fp, "%d", *(A + i * n + j));
}
}
/* allocate memory for B and set values null */
B = calloc(n * p, sizeof(int));
/* read B */
for (i = 0; i < *n; i++) {
fscanf(fp, "\n");
for (j = 0; j < *p; j++) {
fscanf(fp, "%d", *(B + i * p + j));
}
}
/* allocate memory for C and set values null */
C = calloc(m * p, sizeof(int));
/* close FP & free allocated memory */
fclose(fp);
}
It's a bit hard to understand what you are doing in that function, but it seems you just need to better understand pointers in C.
For this line:
A = calloc(m * n, sizeof(int));
What this is doing is it is trying to multiply two pointers, but I'm assuming you want to multiply the values they point to, so you need to prefix m and n with a * to de-reference them (and get their value).
For the assignment to A, what you are trying to do right now, is assign a pointer to a "pointer to a pointer", which is impossible. You need to deference A by prefixing it with a * to get the pointer that it is pointing to, and then you also should be casting the result of calloc to (int*) to match what you are assigning to.
Example:
*A = (int*)calloc(*m * *n, sizeof(int));
The same rules apply to the other errors in the code.
Let's look at your first error. The variables involved are declared as int *m, int *n, so pointers to ints.
On line 13:
A = calloc(m * n, sizeof(int));
The error is due to m * n. You're saying multiply pointer m with pointer n. That makes no sense. What you probably mean is to multiply the values pointed to by those pointers: (*m) * (*n).
Those to be honest, I don't see why you made m and n pointers in the first place.
Also, A is declared as a pointer to a pointer. That probably means you also want *A.
I'd recommend you read up on pass-by-value vs. pass-by-address.

C - Segmentation Fault with dynamic allocations

I'm doing this program to find the saddle point of a matrix (elements there are the greatest number on their column and at the same time the smallest on their row)
So, here is the thing, I'm getting a Segmentation Fault. When using windows, it works fine actually, but when I'm going to run on Ubunto, it doesn't work. I, unfortunitely, only have windows on my machine, so I can't figure out why it is not working or where it is going wrong.
Could you guys help me out? Tell me what is wrong with the code, or where is the error please!
int main(){
int i, j, *ml, *mc, key = 1, z;
int ordem, **me;
char car;
/* ml = smallest of each row, mc = greatest of each column
* me = given matrix
* ordem = size of matrix */
scanf("%d", &ordem);
me = malloc(ordem * sizeof(int));
for(i = 0; i < ordem; i++){
me[i] = malloc(ordem * sizeof(int));
}
ml = malloc (ordem * sizeof(int));
mc = malloc (ordem * sizeof(int));
for(i = 0; i < ordem; i++){
scanf("%d", &me[i][0]);
for(j = 1; j < ordem; j++){
scanf(" %d", &me[i][j]);
}
do{
z = scanf("%c", &car);
}while ((z != EOF) && (car != '\n'));
}
If necessary, I can give you guys the rest of the code, but I'm quite sure that the error is happening in there, either on the malloc or the scanf.
Thanks a lot, really appreciate any help! Best regards!
int **me;
me = malloc(ordem * sizeof(int));
here is the mistake ! It's :
me = malloc(ordem * sizeof(int*));
Always double check your malloc, 90% of the segfault comme from here ...
Your issue is probably on the line
me = malloc(ordem * sizeof(int));
me is a int**, so you need to allocate for int*, not int.
This is giving you portability issues because different compilers do not necessarily use the same size for those data types. Try running this code on the different machines to test what is going on.
printf("The size of an int is %d\n", sizeof(int));
printf("The size of an int* is %d\n", sizeof(int*));
A way that you can modify your coding style so that this error is harder to make is to use the variable name in your sizeof like so
me = malloc(ordem * sizeof(*me));
This way you can visually see that you are allocating space for ordem variables of the type that me points to.
When you allocate the pointer array you need to take the element size of the pointer, not int. On your Ubuntu system the pointer size is probably 64 bit while ints are still 32, while on Windows both have the same size as was traditionally the case.

C array of pointers and malloc

I'm trying to get data from std stored into an array, using pointers. The main declares d as int *d; and the function is called using x = getdata(&d); When I step through it with gdb it dies at the first iteration of the for loop, when it tries *d[i]=val;
int getdata(int **d)
{
int count,val,i,j=0;
scanf("%d", &count);
d = malloc(sizeof *d * count);
for( i = 0; i < count-1; i++) {
scanf("%d",val);
*d[i]=val;
}
for ( i = 0; i < count; i++)
printf("Number %d\n",*d[i]);
return count;
}
The memory should be allocated as follows
*d = malloc(count * sizeof **d);
The values should be accessed as follows
(*d)[i] = val;
It is also not clear why you allocate count elements and only initialize count - 1 elements in the input cycle (and later print all count elements in output cycle).
*d = malloc(count * sizeof(int));
then
(*d)[i] = val
What you have is a pointer to an array, not an array of pointers.
1) malloc returns a void* so you need to assign the result to *d instead of d
2) the data size you want is of an int, not an int* (using *d gets you an int* where **d is an int)
*d = malloc(sizeof(**d) * count);
3) Indexing the array requires slightly different syntax
(*d)[i] = val;
printf("%d\n", (*d)[i]);
4) The second scanf needs a pointer, not an int
scanf("%d", &val);

Resources