Incomplete copy from struct to array - c

I have defined:
#define arrayLengthInStruct 50
typedef struct {
struct {
int _buf[arrayLengthInStruct];
int _bufLen;
} _context;
} _handle;
in main()
_handle handlePtr;
_handle* handle = (_handle*) &handlePtr; // data is here
int* k_src = NULL; // to be loaded to
int i = 0;
handlePtr._context._bufLen = arrayLengthInStruct;
// initialize the source
for (i = 0; i < handlePtr._context._bufLen; i++) {
handlePtr._context._buf[i] = i+1;
printf("%d \t", handlePtr._context._buf[i]);
}
printf("\n");
k_src = malloc(sizeof(int)*(handlePtr._context._bufLen));
printf("Amount of data to copy: %d \n", handle->_context._bufLen);
memcpy ( k_src,
&handle->_context._buf[0],
handle->_context._bufLen
);
for (i = 0; i < handlePtr._context._bufLen; i++) {
printf("%d \t", k_src[i]);
}
printf("\n");
However, the copy is incomplete. What am I missing?
output:
/*
1 2 3 4 5 6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49 50
Amount of data to copy: 50
1 2 3 4 5 6 7 8 9 10 11 12 13
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
*/

The third argument to memcpy is the number of bytes to copy. You provided the number of ints. Do this instead:
memcpy ( k_src,
&handle->_context._buf[0],
handle->_context._bufLen * sizeof(int)
);

You're missing the fact that memcpy copies a number of bytes rather than integers. You need to multiply your array size by sizeof(int) when using it with memcpy.
On a little-endian machine with four-byte int type, copying 50 bytes would give you what you see (50 / 4 = 12.5) though the last element 13 would depend on what was already in the destination memory.

Related

Advanced Number Pattern

Given a Number N, Print the following pattern.
Input Format
The input contains a number N
Constraints
1 < N < 100
Output Format
The required pattern
for input 5 is
1
2 9
3 8 10
4 7 11 14
5 6 12 13 15
and for input 3 is
1
2 5
3 4 6
this is the code i have tried .. but the results are not the same
#include<stdio.h>
void pattern(int n)
{
for(int i=1; i<=n; i++)
{
int k = i;
for(int j=1; j<=i; j++)
{
printf("%d ",k);
k = n - j + k;
}
printf("\n");
}
}
int main()
{
int n = 5;
pattern(n);
return 0;
}
this is the result of the above code
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
How should I modify the above code to get the Expected Output?
This is an interesting problem, and not an easy one. I'm not going to write a program to solve it (in part because I'm too lazy), but I can describe how I would solve it.
You already have an outer loop for(int i=1; i<=n; i++) which counts down the rows, and an inner loop for(int j=1; j<=i; j++) which counts across the columns. Those are both fine.
Inside the inner loop I would test if(j % 2 == 1). If j % 2 is 1 we're in an odd-numbered column, and we want to count down the column. But if j % 2 is 0, we're in an even column, and we have to do it the other way.
First I would have a variable which is the number that's supposed to be at the top of the column (1, 9, 10, 14, or 15 in the n=5 case). I'd have to compute that number two different ways, one for the "odd" columns and one for the "even".
And then I'd use that number as a base to count down the odd columns, and up the evens. Specifically: I'd add i to it in the odd columns, but subtract i in the even columns. But actually that's not quite right, because i is not 1 at the top of columns other than 1, so what I'd actually have to add or subtract would be some function of i and j. But I think you can work this out.
Here are my three cents.:)
#include <stdio.h>
int main(void)
{
while ( 1 )
{
const unsigned int UPPER_LIMIT = 100;
printf( "Enter a non-negative number no greater than %u (0 - exit): ",
UPPER_LIMIT );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( !( n < UPPER_LIMIT ) ) n = UPPER_LIMIT - 1;
putchar( '\n' );
for ( unsigned int i = 0; i < n; i++ )
{
for ( unsigned int j = 0; j < i + 1; j++ )
{
unsigned int value = j % 2 == 0
? i + 1 + j * n - j * ( j + 1 ) / 2
: ( j + 1 ) * n - j * ( j + 1 ) / 2 - i + j;
printf( "%2u ", value );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
The program output might look the following way
Enter a non-negative number no greater than 100 (0 - exit): 10
1
2 19
3 18 20
4 17 21 34
5 16 22 33 35
6 15 23 32 36 45
7 14 24 31 37 44 46
8 13 25 30 38 43 47 52
9 12 26 29 39 42 48 51 53
10 11 27 28 40 41 49 50 54 55
Enter a non-negative number no greater than 100 (0 - exit): 9
1
2 17
3 16 18
4 15 19 30
5 14 20 29 31
6 13 21 28 32 39
7 12 22 27 33 38 40
8 11 23 26 34 37 41 44
9 10 24 25 35 36 42 43 45
Enter a non-negative number no greater than 100 (0 - exit): 8
1
2 15
3 14 16
4 13 17 26
5 12 18 25 27
6 11 19 24 28 33
7 10 20 23 29 32 34
8 9 21 22 30 31 35 36
Enter a non-negative number no greater than 100 (0 - exit): 7
1
2 13
3 12 14
4 11 15 22
5 10 16 21 23
6 9 17 20 24 27
7 8 18 19 25 26 28
Enter a non-negative number no greater than 100 (0 - exit): 6
1
2 11
3 10 12
4 9 13 18
5 8 14 17 19
6 7 15 16 20 21
Enter a non-negative number no greater than 100 (0 - exit): 5
1
2 9
3 8 10
4 7 11 14
5 6 12 13 15
Enter a non-negative number no greater than 100 (0 - exit): 4
1
2 7
3 6 8
4 5 9 10
Enter a non-negative number no greater than 100 (0 - exit): 3
1
2 5
3 4 6
Enter a non-negative number no greater than 100 (0 - exit): 2
1
2 3
Enter a non-negative number no greater than 100 (0 - exit): 1
1
Enter a non-negative number no greater than 100 (0 - exit): 0
Or using the recursive approach of calculating the output value the program can look the following way.
#include <stdio.h>
int main(void)
{
while ( 1 )
{
const unsigned int UPPER_LIMIT = 100;
printf( "Enter a non-negative number no greater than %u (0 - exit): ",
UPPER_LIMIT );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( !( n < UPPER_LIMIT ) ) n = UPPER_LIMIT - 1;
putchar( '\n' );
for ( unsigned int i = 0; i < n; i++ )
{
unsigned int value = i + 1;
for ( unsigned int j = 0; j < i + 1; j++ )
{
printf( "%2u ", value );
value += j % 2 == 0 ? 2 * ( n - i ) - 1 : 2 * ( i - j );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
For example its output for the entered number equal to 10 looks like
Enter a non-negative number no greater than 100 (0 - exit): 10
1
2 19
3 18 20
4 17 21 34
5 16 22 33 35
6 15 23 32 36 45
7 14 24 31 37 44 46
8 13 25 30 38 43 47 52
9 12 26 29 39 42 48 51 53
10 11 27 28 40 41 49 50 54 55
Enter a non-negative number no greater than 100 (0 - exit): 0

Array is printing with weird question mark symbols when printing fibonacci sequences

When printing each Fibonacci sequence the first couple of sequences print in weird symbols or not at all if printing more than 8 sequences.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//n=amount of numbers in the series to compute, seq=array to store series
void fibonacci(int n, int* seq){
// Complete this function
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i <= n; i++){
seq[i] = seq[i-2] + seq[i-1];
}
}
int main(){
int n;
//n, amount of series to compute
scanf("%d",&n);
//initialize array to 1, using malloc/calloc
int *seq = malloc(1 * sizeof(*seq));
int i;
for(i = 1; i <= n; i++){
//recompute the whole series
fibonacci(i, seq);
//print array
int j;
for(j = 0; j < i; j++)/* complete code */
printf("%d ", seq[j]);
//resize array, with realloc
int newSize=i+1;
int *seq = realloc(seq, newSize);
printf("\n");
}
//free array
return 0;
}
Output:
"7Y��yb�=
Um�*/E�o 1 1 2 3 5 8 13
0 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8 13 21 34
0 1 1 2 3 5 8 13 21 34 55
0 1 1 2 3 5 8 13 21 34 55 89
0 1 1 2 3 5 8 13 21 34 55 89 144
0 1 1 2 3 5 8 13 21 34 55 89 144 233
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
There are different problems in your code:
In your fibonacci() function, you iterate using i <= n, but inside the loop, you assign to seq[i]. When i = n, this becomes a problem: you're accessing one cell out of the array.
You are getting n from user input, but then doing int *seq = malloc(1 * sizeof(*seq)). You are only allocating space for one element, not n. You should do malloc(n * sizeof(*seq)) instead.
Not really an error, but inside the first for loop in your main, you're both re-defining and re-allocating the seq array with int *seq = realloc(...). That is not needed at all. Your array is already n cells big, so there is no need to reallocate it each time. You can use it as is.
Not really an error, but there is no need to recompute the series each time. You can compute it only once and then partially print it on each row without a problem.
Also, IMPORTANT! Using int to hold numbers of the Fibonacci sequence is only good until you reach n = 47. More than that, and your next element will overflow the maximum positive value that an int can hold, turning negative, and invalidating the rest of the calculations too. I would suggest you to use long long unsigned int instead, which would be good up to n = 94 (assuming 64 bits). Ultimately, you should check the value of n before calculating the Fibonacci sequence to avoid an overflow.
Here's a better version of your code with those problems fixed:
void fibonacci(int n, int* seq) {
int i;
seq[0] = 0;
seq[1] = 1;
for(i = 2; i < n; i++)
seq[i] = seq[i-2] + seq[i-1];
}
int main() {
int *seq;
int n, i, j;
scanf("%d",&n);
// Allocate enough space for n elements:
seq = malloc(n * sizeof(*seq));
// Compute the whole series once:
fibonacci(n, seq);
// Print partial series on each row:
for(i = 1; i <= n; i++) {
for(j = 0; j < i; j++)
printf("%d ", seq[j]);
printf("\n");
}
free(seq);
return 0;
}

How can i read a string from a file which is before a integer

I have this text file:
2 6
99 100 14 15 1 4 29 43 15 15
31 24 2 0 2 0 2 0 12 12
1 5 2 6 3 50 2 0 1 100
31 24 2 0 2 0 2 0 12 12
99 100 14 15 1 4 29 43 15 15
Lucky 0 0 100 100
James 2 0 100 100
Jerry 2 4 100 100
Cristofor 0 2 100 100
Chris 2 3 100 100
Miclaus 2 1 100 100
I want to read all data in multiple structures.
This is my code: I read first 6 lines and i want to read next 6 and put every word in variables. I don t know how to read that string.
void citireDate(){
char c;
FILE *f;
f = fopen("nume.in","r");
fscanf(f,"%d", &R);
fscanf(f,"%d", &P);
for(int i=1;i <= 2*R+1 ; i++)
for(int j=1;j <= 2*R+1; j++){
fscanf(f,"%d",&ghetar[i][j].inaltime);
fscanf(f,"%d",&ghetar[i][j].manusi);
}
for(int i=1;i<=6;i++){
//here i have to read that string
fscanf(f,"%d",&spiridusi[i].x);
fscanf(f,"%d",&spiridusi[i].y);
fscanf(f,"%d",&spiridusi[i].hp);
fscanf(f,"%d",&spiridusi[i].stamina);
}
fclose(f);
}
How can i read that string?
just read all the line in one fscanf(f, "%s %d %d %d %d\n", ...);
for(int i=1;i<=6;i++) {
fscanf(f, "%s %d %d %d %d\n",
&spiridusi[i].?????,
&spiridusi[i].x,
&spiridusi[i].y,
&spiridusi[i].hp,
&spiridusi[i].stamina);
}
Or course I suppose there is no space in the string before the 4 integers
It is strange the first indexes are always 1, I think they must be 0 in all the for (except if you have a good reason to start by 1)

MPI gatherv displacement not working as expected

I have the following code which I compile and run with:
mpicc -std=c99 region.c
mpirun -n 4 region
$mpirun -version
mpirun (Open MPI) 1.6.5
$mpicc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int rank,
size,
dims[2],
coords[2],
image_size[2] = {8,8},
local_image_size[2];
MPI_Datatype border_row_t,
border_col_t,
subarray_type,
recv_type;
unsigned char *image,
*region,
*local_region;
void create_types() {
int starts[2] = {0, 0};
MPI_Type_create_subarray(2, image_size, local_image_size, starts, MPI_ORDER_C, MPI_UNSIGNED_CHAR, &subarray_type);
MPI_Type_commit(&subarray_type);
MPI_Type_vector(local_image_size[0], local_image_size[1], image_size[1], MPI_UNSIGNED_CHAR, &recv_type);
MPI_Type_commit(&recv_type);
}
void distribute_image(){
if (0 == rank) {
MPI_Request request;
int num_hor_segments = image_size[0] / local_image_size[0];
int num_vert_segments = image_size[1] / local_image_size[1];
int dest_rank=0;
for (int vert=0; vert<num_vert_segments; vert++) {
for (int hor=0; hor<num_hor_segments; hor++) {
MPI_Isend((image+(local_image_size[0]*hor)+(local_image_size[1]*image_size[1]*vert)), 1, subarray_type, dest_rank, 0, MPI_COMM_WORLD, &request);
dest_rank++;
}
}
}
MPI_Status status;
MPI_Recv(local_region, local_image_size[0]*local_image_size[1], MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD, &status);
}
void gather_region(){
int counts[4]={1,1,1,1};
int disps[4]={0,4,32,36};
MPI_Gatherv(local_region,local_image_size[0]*local_image_size[1], MPI_UNSIGNED_CHAR, region,counts,disps,recv_type,0,MPI_COMM_WORLD);
if (0==rank) {
printf("Actually returned:\n");
for (int i=0; i<image_size[0]*image_size[1]; i++) {
printf("%d\t", *(region+i));
if ((i+1)%image_size[0]==0) printf("\n");
}
}
}
void init_mpi(int argc, char** argv){
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Dims_create(size, 2, dims);
}
void load_and_allocate_images(int argc, char** argv){
if(rank == 0){
image = (unsigned char*) malloc(sizeof(unsigned char*) * image_size[0] * image_size[1]);
for (unsigned char i=0; i<image_size[0]*image_size[1]; i++) {
image[i] = i;
printf("%d\t", *(image+i));
if((i+1)%image_size[0]==0) printf("\n");
}
printf("\n\n");
region = (unsigned char*)calloc(sizeof(unsigned char),image_size[0]*image_size[1]);
}
local_image_size[0] = image_size[0]/dims[0];
local_image_size[1] = image_size[1]/dims[1];
int lsize = local_image_size[0]*local_image_size[1];
int lsize_border = (local_image_size[0] + 2)*(local_image_size[1] + 2);
local_region = (unsigned char*)calloc(sizeof(unsigned char),lsize_border);
}
void cleanup() {
MPI_Type_free(&subarray_type);
MPI_Type_free(&recv_type);
}
int main(int argc, char** argv){
init_mpi(argc, argv);
load_and_allocate_images(argc, argv);
create_types();
distribute_image();
gather_region();
cleanup();
MPI_Finalize();
exit(0);
}
When I run gatherv with displacements of 0, 4, 32 and 36 I get the following
Distributed vector:
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
Actually returned:
0 1 2 3 0 0 0 0
8 9 10 11 0 0 0 0
16 17 18 19 0 0 0 0
24 25 26 27 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
If I change the displacements to 0, 1, 32 36 I get the following:
Distributed vector:
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
Actually returned:
0 1 2 3 0 0 0 0
8 9 10 11 0 0 0 0
16 17 18 19 0 0 0 0
24 25 26 27 4 5 6 7
0 0 0 0 12 13 14 15
0 0 0 0 20 21 22 23
0 0 0 0 28 29 30 31
0 0 0 0 0 0 0 0
Why does a displacement of 1 translate to 28 in the returned vector? This confuses me.
Displacements in MPI_GATHERV are specified in units the extent of the datatype. The datatype as created by MPI_Type_vector(local_image_size[0], local_image_size[1], image_size[1], MPI_UNSIGNED_CHAR, &recv_type); has an extent of {(local_image_size[0]-1) * image_size[1] + local_image_size[1]} * extent(MPI_UNISIGNED_CHAR). Given the following:
local_image_size[0] = 4
local_image_size[1] = 4
image_size[1] = 8
extent(MPI_UNSIGNED_CHAR) = 1 byte
this results in the extent of recv_type being (4-1) * 8 + 4 or 28 bytes. Therefore, displacement of 1 specifies a location 28 bytes past the beginning of the receive buffer.
It is possible to "resize" a type by forcing a different "visible" extent on it with MPI_Type_create_resized. The whole procedure of properly performing 2D decomposition is well described in this answer.

Error in scanf()

first of all, I've got a logical error in my code. Well, this is the code
#include <stdio.h>
int main()
{
long i,j,t;
scanf("%ld",&t);
long n[t],d[t][t];
for(i = 0; i < t;i++){
scanf("%ld",&n[i]);
for(j = 0; j < n[i] ;j++){
scanf("%ld",&d[j][i]);
}
}
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[j][i]);
}
printf("\n");
}
return 0;
}
And I input the data
2
4
25 20 30 90
3
45 50 55
And the result is
25 20 30 90
45 50 55
Well, that's what I expected. However, when the input become like this
3
5
12 67 89 34 56
6
34 56 78 90 12 34
7
12 34 89 23 56 78 89
The result become like this
12 34 89 23 56 78 89
12 67 89 34 56 4206692 7 2293472 1982002386 16 3 2293344 2293408 0 2293552 0 0 4
198585 8918456 1982106837 1982010910 8918456 2293640 0 0 1985286516 2009576437 0
0 2293664 2009323341 2293740 2147348480 0
34 56 78 90 12 34 4199405 1982595752 8 12 2293424 2 2 1982356412 2147348480 2293
608 2147348480 1 -1 297753669 1982010784 1982015505 4199044 0 0 2147348480 21473
48480 0 0 0 7273647 2009576392 0 0 0 1 0 20 52 0 0 438759246 736 -214797894 1420
760826203 2272 852421325 3108 944791496 4028 -1322777276 4988 9 1 1 1204 7168 4
2 152 11832 7 1 40 12316 1682469715 1 140 44 0 0 0 2 0 7209065 5701724 6029427
12 34 89 23 56 78 89
Well, the simple question, why the output become like the above?? When I input above 2, the same result will be happened. Any possible answers and links if you don't mind it?? Thanks
You are writing outside your 2D array in many cases, sometimes you don't get errors, but that's just by chance.
You determine the size of the 2D array by the number of arrays to be inputted, but you also determine the size of the inner arrays at the same time:
scanf("%ld",&t);
long n[t],d[t][t];
So for example, let's take the first example:
2 >> create array n[2], and array d[2][2]
4 >> number of values to d[0]
25 20 30 90 >> d[0][1] = 25 d[0][2] = 20 you access d[0][3] and d[0][4] but you are not allowed to do that.
3 >> number of values to d[1]
45 50 55 >> d[1][0] = 45 d[1][1] = 50 you access d[1][2] but you are not allowed to do that
You build a matrix with size t*t, then fill in rows with more or less elements.
If you fill a row with too few elements, the rest remain uninitialized, and you get strange numbers. It's OK in your case, because you don't print these elements.
If you fill a row with too many elements, the excess overlaps into the next row. It may also exceed the whole matrix and corrupt your stack.
I guess this is what's going on - your n array is overrun, and your code goes crazy.
I believe that you can use malloc.
#include <stdio.h>
#include <stdlib.h>
int main()
{
long i,j,t;
printf("Rows : ");
scanf("%ld",&t);
long *n;
long **d;
n = (long* )malloc(sizeof(long) * t); // add malloc
d = (long** )malloc(sizeof(long *) * t); // add malloc
for(i = 0; i < t;i++){
printf("Column : ");
scanf("%ld",&n[i]);
d[i] = (long* )malloc(sizeof(long) * n[i]); //add malloc
if(d[i] == NULL)
printf("ERROR\n");
for(j = 0; j < n[i] ;j++){
scanf("%ld", &d[i][j]); // change from &d[j][i]
}
}
printf("\n\n");
for(i = 0; i < t;i++){
for(j = 0; j < n[i] ;j++){
printf("%ld ",d[i][j]); // change from d[j][i]
}
printf("\n");
}
return 0;
}
Well, the simple question, why the output become like the above?? When
I input above 2, the same result will be happened. Any possible
answers and links if you don't mind it?? Thanks
because you allocate less memory than used.
scanf("%ld", &d[j][i]); you have to exchange the "i" and "j".

Resources