I'm not exactly sure why this isn't returning what it should be, perhaps one of you could help me out. I have the following for loop in C:
for (i=0; i<nrow; i++) {
dat[k]=l.0;
k++;
}
Now, you would think that this would set all values of dat (of which there are nrow values) to 1.0; Instead, it is being set to 0. The program compiles fine and everything goes smoothly. The memory is properly allocated and dat is defined as a double.
Is there a reason this is yielding 0? I'm guessing the 0 is coming from the initialization of the dat variable (since I used calloc for memory allocation, which supposedly initializes variables to 0 (but not always)).
EDIT: Please note that there is a specific reason (this is important) that I'm not defining it as dat[i]. Additionally. k was defined as an integer and was initialized to 0.
EDIT 2: Below is the entire code:
#include "stdio.h"
#include "stdlib.h"
#define NCH 81
// Generate swap-mode data for bonds for input.conf file
int main()
{
int i,j,k;
int **dat2;
double *dat;
int ns = 500;
int nrow = NCH*(ns-1);
dat = (double*) calloc(nrow, sizeof(double));
dat2 = (int**) calloc(nrow,sizeof(int*));
/*for (i=0; i<nrow; i++) {
dat2[i] = (int*) calloc(2, sizeof(int));
for (j=0; j<2; j++)
dat2[i][j] = 0;
}*/
k=0;
printf("\nBreakpoint\n");
/*for (i=0; i<81; i++) {
for (j=0; j<250; j++) {
dat[k] = j+1;
k++;
}
for (j=251; j>1; j++) {
dat[k] = j-1;
k++;
}
}*/
FILE *inp;
inp = fopen("input.out", "w");
for (i=0; i<nrow; i++) {
dat[k]=1.0;
k++;
}
//fprintf(inp, "%lf\n", dat[i]);
printf("%d", dat[nrow]);
printf("\nDone\n");
fclose(inp);
return 0;
}
Thanks!
Amit
printf("%d", dat[nrow]);
is not valid, because the nrow'th element of dat doesn't exist.
Are you sure you are starting 'k' at zero?
In the sample you posted you are using l not 1 - is this just a typo?
for (i=0; i<nrow; i++) {
dat[k]=1.0;
k++;
}
That should work.
Two things:
I'm assuming the l.0 is a type and your l is actually a 1.
Secondly, why are you using k in your for loop instead of using i? Try using this instead:
for (i=0; i<nrow; i++) {
dat[i]=1.0;
}
Either this works your compiler/hardware is bugged.
k = 0;
for (i=0; i < nrow; i++) {
dat[k++] = 1.0f;
}
printf("%d, %d", dat[0], dat[nrow - 1]);
when you printf("%d", dat[nrow]), dat[nrow] has not been set to 1. In the for loop the condition is i < nrow so it's before it. You need i <= nrow.
Related
I am trying to copy a 1D array of Strings into a 2D array of strings in C.
I was able to achieve this with integer
enter image description here
//Here is what I tried for integers.
int main()
{
int arr[3][3];
int arr2[9]={1,2,3,4,5,6,7,8,9};
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%2d ", arr[j][i]);
printf("\n");
}
return 0;
}
I changed my data to char and I tried to run the same code I got a segmentation error.
Here is what I have tried so far and it didnt work. error :Segmentation fault (core dumped)
#include<stdio.h>
#include<string.h>
int main()
{
char *d[3][3]; // Destination array
char *s[9]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;i++){
strcpy(d[j][i], s[i]);
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
I have made some adjustment and now it print some weird strings
#include<stdio.h>
#include<string.h>
int main() {
char d[3][3] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
int i,j,k=0;
for(i=0; i<3;i++){
for(j=0; j<3;j++){
d[j][i] = *s[i];
}
}
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", &d[j][i]);
printf("\n");
}
return 0;
}
enter image description here
This for loop
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[i];
//rintf("%d\n",arr2[i]);
}
}
is incorrect. In the inner loop there are used the same elements arr2[i] where i is changed from 0 to 2 inclusively.
You need to write
for(i=0; i<3;i++){
for(j=0; j<3;i++){
arr[j][i] = arr2[ 3 * i + j];
}
}
Another way to write loops is the following
for ( i = 0; i < 9; i++ )
{
arr[i / 3][i % 3] = arr2[i];
}
As for arrays of pointers of the type char * then the nested loops will look similarly
for(i=0; i<3;i++){
for(j=0; j<3;i++){
d[i][j] = s[ 3 * i + j];
}
}
provided that the array s is declared like
char * s[9]={"orange","apple","table","chair","cable","TV", "124","HI"};
And to output the result array you need to write
for(i=0; i<3; i++) {
for(j=0; j<3; j++)
printf("%s ", d[i][i]);
^^^^^^^
printf("\n");
}
As for your last program then it can look like
#include<stdio.h>
#include<string.h>
int main( void )
{
char d[3][3][8] ={0}; // Destination array
char s[9][8]={"orange","apple","table","chair","cable","TV", "124","HI"}; // Source 1 Day array
for( size_t i = 0; i < 3; i++ )
{
for ( size_t j = 0; j < 3;j++ )
{
strcpy( d[j][i], s[3 * i + j] );
}
}
for ( size_t i = 0; i < 3; i++ )
{
for ( size_t j = 0; j < 3; j++ )
{
printf( "%s ", d[i][j] );
}
putchar( '\n' );
}
return 0;
}
Some issues ...
d is unitialized so the pointers within point to random locations.
To fix, we need to use malloc to get space and then do strcpy. An easier way is to just use strdup. Or, just assign the s value directly.
Your j loop should increment j and not i.
Using s[i] will repeat after three elements. To fix, we can do: s[k++]
You are short one initializer for s (i.e. it is length 9 but you have only 8 strings).
Here is the refactored code:
#include <stdio.h>
#include <string.h>
int
main(void)
{
char *d[3][3]; // Destination array
char *s[9] = {
"orange", "apple", "table", "chair", "cable", "TV", "124", "HI",
#if 1
"raindrops"
#endif
}; // Source 1 Day array
int i, j, k = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
// NOTE/BUG: we must allocate space for d[j][i]
#if 0
strcpy(d[j][i], s[i]);
#else
d[j][i] = strdup(s[k++]);
#endif
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
printf("%s ", d[j][i]);
printf("\n");
}
return 0;
}
Here is the output:
orange apple table
chair cable TV
124 HI raindrops
There's numerous big problems here.
You could have simply solved this with memcpy(arr, arr2, sizeof *arr2);
(Probably the least of your problems, but...) This is badly written performance-wise: for(j=0; j<3;i++){ arr[j][i] = arr2[i]; Multiple loops should always have the inner-most loop work with the inner-most array item, in this case it should have been arr[i][j], or you get needlessly bad data cache performance.
for(j=0; j<3;i++) How about j++.
char *d[3][3]; is an uninitialized 2D array of pointers, each pointing at la-la-land. So you can't copy jack into those addresses - pointers need to point at valid, allocated memory.
char d[3][3] is a 2D array of 3x3 characters, so it can't contain the data you wish to store there, let alone the mandatory null terminators required for strings to work.
char *s[9] = ... In case you meant the 9th item to be NULL, a so-called sentinel value, you should type out NULL explicitly or otherwise the reader can't tell if a NULL sentinel is intended or if you just sloppily added one by accident.
As you can tell from previous comments, the overall slopiness is a recurring major problem here. Take for example:
for(j=0; j<3; j++)
printf("%s ", &d[j][i]);
printf("\n");
Because of sloppy indention, we can't tell if the printf("\n"); was intended to sit inside the inner loop or not (it is not, despite the indention). You can't just type some almost correct stuff down in a hurry. You have to carefully type down actually correct code. There's various myths that great programmers are smart, great at math or abstract thinking etc - in reality, great programmers are careful and disciplined, taking some pride in their own craft.
The quick & dirty fix is to use the second example char* d[3][3] and then instead of strcpy use strdup (currently non-standard, soon to become standard):
for(size_t i=0; i<3; i++){
for(size_t j=0; j<3; j++){
d[i][j] = strdup(s[i]);
}
}
(And ideally also call free() for each item in d at the end.)
But the root problem here is that you need to go back and carefully study arrays, pointers and strings, in that order, before using them.
I tried everything I could think off. I don't know if I'm missing something obvious. Why does this work:
#include<stdio.h>
void test_matrix(int** matrix)
{
for(int i=0; i<4; i++) {
for(int j=0; j<4; j++) {
printf("%d ", *(matrix+j+4*i));
}
}
/**
for(int i=0; i<4; i++) {
for(int j=0; j<4; j++) {
printf("%d ", *(*(matrix+i)+j));
}
}
*/
}
int main()
{
int matrix[4][4];
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
scanf("%d", &matrix[i][j]);
test_matrix(matrix);
}
But the commented section doesn't work. I also tried matrix[i][j] and it still won't work. My program times out.
EDIT: I added the function calling in MAIN.
The error is that this 2D-array is laid out as 4 x 4 = 16 integers. But your function expects a pointer to pointers.
It's right that at the calling site the address of matrix is provided as the argument. But unlike some commenter said, it's not a pointer to int but a pointer to an int-array.
To handle this address of the 2D-array correctly you need to tell it your function, like this:
void test_matrix(int (*matrix)[4])
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", *(*(matrix + i) + j));
}
}
}
or like this:
void test_matrix(int matrix[][4])
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
}
}
Which kind of access you use doesn't matter, sometimes it's just a matter of taste. These expressions are equivalent, actually p[i] is syntactic sugar for *(p + i):
*(*(matrix + i) + j)
matrix[i][j]
Note 1: As some commenters already recommend, you should raise the warning level to the maximum and correct the source until all diagnostics are handled.
Note 2: When your arrays vary in their dimensional sizes you need to think of a way to tell these sizes to your function.
I try to print out two arrays with the following function using XCode 6.1.1:
for (int j=0; j<4; j++) {
for (int k=0; k<4; k++) {
printf("%2d ", Lattice[0][j+N*k]);
}
printf(" ");
for (int k=0; k<4; k++) {
printf("%2d ", Lattice[1][j+N*k]);
}
printf("\n");
}
printf("\n");
Everything works fine when calling the function,
as long as I don't print out a float before.
When printing an int, there's no problem. So it's a
little strange, right?
I'm initializing the array like this:
int **Lattice = (int**)malloc(2*sizeof(int*));
if (Lattice == NULL) return NULL;
for (int i=0; i<2; i++){
Lattice[i] = (int *)malloc(2*sizeof(int));
if (Lattice[i] == NULL) {
for (int n=0; n<i; n++)
free(Lattice[n]);
free(Lattice);
return NULL;
}
else{
for (int j=0; j<N; j++) {
for (int k=0; k<M; k++) {
Lattice[i][j+N*k] = 0;
}
}
}
}
return Lattice;
Too bad, I can't upload an image of the output.
The matrices should show only zeros, but with the float
there will be big numbers in some entries which i can't explain.
I'm grateful for any hints.
Thank you.
So your code has some pretty serious problems.
Lattice[0] and Lattice[1] need to have dimensions 4x4 for your printing block of code to make any sense. Incidentally this means N and M need to equal 4 as well or you need to change your printing for loop conditions to j < N and k < M respectively.
Your malloc needs to allocate space for that as well, so: Lattice[i] = (int *)malloc(N * M * sizeof(int));
This should cause your loops to work correctly, but you do not have floats anywhere in your code. You cannot use printf to print an int as a float. The value will not be promoted. It will simply be treated as a float.
gcc 4.6.2 c89
Allocating memory for a 2D array and filling with characters.
However, I don't seem to be filling as when I print nothing is displayed.
Am I doing something wrong here?
char **attributes = NULL;
/* TODO: Check for memory being allocated */
attributes = malloc(3 * sizeof(char*));
int i = 0;
int k = 0;
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
sdp_attributes[i][k] = k;
}
}
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
printf("attributes[i][k] [ %c ]\n", attributes[i][k]);
}
}
Many thanks for any advice,
Two major issues:
First Issue:
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
You are reallocating sdp_attributes[i] at each iteration of the inner loop - thereby overwriting it each time. You probably wanted this instead:
for(i = 0; i < 3; i++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
for(k = 0; k < 5; k++) {
Second Issue:
sdp_attributes[i][k] = k;
You are basically writing the lower ascii characters. Most of them are not printable.
Something like this might do what you want:
sdp_attributes[i][k] = k + '0';
You probably want:
for (i = 0; i < 3; i++)
{
attributes[i] = malloc(5 * sizeof(char));
for (k = 0; k < 5; k++)
{
attributes[i][k] = k;
}
}
This ignores error checking on the allocation.
It also fixes the name of the array to match the declaration, but your code either wasn't compiling (don't post non-compiling code unless your question is about why it doesn't compile!) or you have another variable called sdp_attributes declared somewhere which you weren't showing us.
Your code was leaking a lot of memory. Each time around the k-loop, you allocated a new array of 5 characters and stored the pointer in attributes[i] (or sdp_attributes[i]), storing the new pointer over what was there before, so you overwrote the value of the first 4 pointers. You could not possibly free the first four items - they were lost irretrievably. Also, on the last iteration, you initialized the 5th element of the final array, but the previous 4 were not initialized and therefore contained indeterminate garbage.
Also, in your printing loop, the values in the array are control characters ^#, ^A, ^B, ^C and ^D; these do not necessarily print well with %c (especially not ^#, which is also known as NUL or '\0'). The printf() statement might be better written as:
printf("attributes[%d][%d] [ %d ]\n", i, k, attributes[i][k]);
This prints the array indexes (rather than simply the characters [i][k] for each entry), and prints the control characters as integers (since the char values are promoted to int when passed to printf()) rather than as control characters.
(It's also more conventional to use i and j for a pair of nested loops, and i, j, and k for triply nested loops, etc. However, that's a very minor issue.)
for(i = 0; i < 3; i++) {
for(k = 0; k < 5; k++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
sdp_attributes[i][k] = k;
}
}
Your erasing the allocated memory every time you loop in the inner most loop.
Here is a correct version.
for(i = 0; i < 3; i++) {
sdp_attributes[i] = malloc(5 * sizeof(char));
for(k = 0; k < 5; k++) {
sdp_attributes[i][k] = k;
}
}
And you should fix your declaration:
attributes = malloc(3 * sizeof(char*));
to
sdp_attributes = malloc(3 * sizeof(char*));
Don't forget to free up all the memory allocated
for(i = 0; i < 3; i++)
{
free(sdp_attributes[i]);
}
free(sdp_attributes);
The correct way to allocate and assign elements to 2d array is as follows (but this is a int array, you can try and change it for char array):
One thing to note: As mentioned by #Mysticial, you should add/subtract '0' to your int value to get the char value when using ASCII character set (remember our itoa() functions!).
#include <stdio.h>
#include <stdlib.h>
int main()
{
int row, column;
int **matrix;
int i, j, val;
printf("Enter rows: ");
scanf("%d", &row);
printf("Enter columns: ");
scanf("%d", &column);
matrix = (int **) malloc (sizeof(int *) * row);
for (i=0 ; i<row ; i++)
matrix[i] = (int *) malloc (sizeof(int) * column);
val=1;
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
matrix[i][j] = val++;
}
}
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
for (i=0 ; i<row ; i++)
free(matrix[i]);
free(matrix);
return 0;
}
Few points to note:
error handling should be added for malloc()
malloc()'ed memory must be free()'ed
While starting on a program for getting a matrix's Reduced Row Echelon Form, I transferred my code for printing the array into its own function. As soon as I did this, I got a segfault. What puzzled me though, was the fact that an unrelated variable declaration (commented below) solved the segfault.
#include <stdio.h>
int COLS = 3;
int ROWS = 3;
void PrintArray(int array[][COLS]);
int main (int argc, char**argv) {
int i, ii = 0;
FILE *file;
file = fopen(argv[1], "r");
int array[ROWS][COLS];
fscanf(file, "%d %d", &ROWS, &COLS);
while (!feof(file))
{
fscanf(file, "%d", &array[i][ii]);
ii++;
if (fgetc(file) == '\n') {
i++;
ii = 0;
}
}
int j = 0, k = 0; //This solved the segfault.
PrintArray(array);
printf("\n");
fclose(file);
return 0;
}
void PrintArray(int array[][COLS]) //The printing function
{
int j, k;
for (j = 0; j < ROWS; j++)
{
for (k = 0; k < COLS; k++)
{
printf("%d", array[j][k]);
}
printf("\n");
}
}
After a couple hours of debugging, I eventually figured out that it may have had something to do with the scope of the variables within the for loop.
To illustrate:
int COLS = 3;
int ROWS = 3;
int a; //declared globally
//main
for (a = 0; a < ROWS; a++) {
printf("for loop");
}
works, but as soon as I declare "a" in main:
int COLS = 3;
int ROWS = 3;
//main
int a; //declared in main
for (a = 0; a < ROWS; a++) {
printf("for loop");
}
it doesn't work.
Also, if I replace the global variables with numbers, I still get a segfault, until I remove the line which originally fixed the segfault!
void PrintArray(int array[][3]) //COLS
{
int j = 0, k = 0;
for (j = 0; j < 3; j++) //ROWS
{
for (k = 0; k < 3; k++) //COLS
{
printf("%d", array[j][k]);
}
printf("\n");
}
}
This appears to be as far as I can get to understanding the problem, so your help would be appreciated.
You are getting out of array bounds. The two extra variables lay right after the array on the stack, so you begin corrupting them instead of something else, that's why segfault is “solved” (it's not solved, of course, the bug is still there).
There are severe problems with that code:
Variable i is used without being initialized
The array size is always 3x3. Reading new values for ROWS and COLS does NOT resize the array. If e.g. you have read ROWS=4 and COLS=4 from file, you will corrupt the memory outside of that allocated for array.