Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Below program is crashing with segmentation for large n (n > 200), can you please help me out here.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
struct node {
char name[16];
char num[8];
};
int main() {
int n, i,j;
struct node *hash;
scanf("%d",&n);
hash = (struct node *) malloc(n * sizeof(struct node));
for (i=0; i<n ; i++) {
scanf("%s %s", (hash + (i *sizeof(struct node)))->name,
(hash + (i *sizeof(struct node)))->num);
}
for (i=0; i<n ; i++) {
printf("%s=%s\n",(hash + (i *sizeof(struct node)))->name,
(hash + (i *sizeof(struct node)))->num);
}
return (0);
}
When you add an integer to a pointer, the compiler performs the pointer arithmetic. So hash + i is translated by the compiler into something like (char*)hash + i * sizeof(struct node). The offset in bytes is calculated for you, and then applied in bytes.
Your code is therefore equivalent to
(char*)hash + i * sizeof(struct node) * sizeof(struct node)
This will reach beyond the array boundary very fast, invoking undefined behavior.
As the comments summarized, either use (hash + i) or the more concise (in my opinion) hash[i].
#include <stdio.h>
#include <stdlib.h>
struct node {
char name[16];
char num[8];
};
int main(void) {
size_t n;
if (scanf("%zu", &n) != 1) {
return 1;
}
struct node *hash = malloc(n * sizeof *hash);
if (hash == NULL) {
return 1;
}
for (size_t i = 0; i < n; i++) {
if (scanf("%15s %7s", hash[i].name, hash[i].num) != 2) {
free(hash);
return 1;
}
}
for (size_t i = 0; i < n; i++) {
printf("%s %s\n", hash[i].name, hash[i].num);
}
free(hash);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
I'm trying to add the index of a value, if it is ==1, to a list in C. Is this even possible? How would I go about it?
this is the general code I have so far:
int ones[256];
int index;
for (index = 0; index < sizeof(input); i++) {
if (input & 1 == 1) {
count = count + 1;
ones.append() = index;
}
You have to implement append yourself. You probably want to wrap that implementation using an array struct that tracks both the length and the elements (optionally you can track capacity and over-allocate). A basic mockup looks like this:
#include <stdio.h>
#include <stdlib.h>
void append(int** array, size_t* length, int element) {
*array = (int*) realloc(*array, 1 + *length);
(*array)[*length] = element;
*length += 1;
}
void print(int* array, size_t len) {
printf("Array(%lu): ", len);
for (size_t i = 0; i < len; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
int main() {
int* array = (int*)malloc(0);
size_t len = 0;
print(array, len);
append(&array, &len, 0);
append(&array, &len, 1);
append(&array, &len, 2);
print(array, len);
}
This question already has answers here:
Using pointer after free()
(6 answers)
Closed 9 months ago.
#include <stdio.h>
#include <stdlib.h>
void printArr(int *ptr, int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%d\t", ptr[i]);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
int *ptr;
ptr = (int *)malloc(4*sizeof(int));
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
ptr[3] = 4;
printArr(ptr, 4);
free(ptr);
printArr(ptr, 4);
return 0;
}
Output :
1 2 3 4
-362921936 26425 2043 4
**Sorry for noobish question i just started learning about dynamic memory allocation. **
The memory in question has in fact been freed. Reading from memory after it has been freed triggers undefined behavior.
"Garbage" values can be anything, including 0 or whatever might have been there before.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
f(x) = a0 + a1*x + a2*x2+...+an*xn
Firstly I create a dynamic array to store the values of an.
Then I define a function to describe the Horner's rule, but however I change the way of doing output, I just get an enormous number. What's wrong with the code?
#include <stdio.h>
#include <malloc.h>
int f(int n, int *p, int x);
int main() {
int *pA;
int length;
int x;
int i;
printf("input the length of Array:"); ///createArray of 'An'
scanf("%d", &length);
printf("please input x = ");
scanf("%d", &x);
pA = (int *)malloc(4 * length);
for (i = 0; i < length; i++) {
printf("input the No.%d element:", i + 1);
scanf("%d", &pA[i]);
}
printf("%d\n", f(length, pA, x)); ///Horner's rule
return 0;
}
int f(int n, int *p, int x) {
int i;
int pn = p[n - 1];
for (i = n; i >= 1; i--) {
pn = p[i - 2] + x * pn;
}
return pn;
}
Given the polynomial
f(x) = a0 + a1x + a2x2 + ... + anxn
The Horner's rule let us evalute it with this formula
f(x) = a0 + x(a1 + x(a2 + ... x(an-1 + xan) ... ))
We can translate it into a recurrence formula and traverse the array of coefficients backwards.
fn = an
fi = ai + x⋅fi + 1
Remembering that the actual size of said array would be n + 1 and that there is a well known idiom used to traverse an array in that way, a possible implementation of the function could be the following.
double evaluate_poly_using_horner(size_t n, int const *c, double x)
{
if ( n == 0 )
return 0.0;
double result = c[n - 1];
for( size_t i = n - 1; (i--) > 0; )
{
result = c[i] + x * result;
}
return result;
}
This would solve the problem in OP's code, where the condition i >= 1 causes the body of the loop to be executed down to i == 1, resulting in an access out bounds of the array p (p[i - 2] = ... becomes p[-1] = ...).
Also note that the lines
#include <malloc.h>
// ...
int *pA;
// ...
pA = (int *)malloc(4 * length);
// ^^^^^^^ ^
// ...
Could be written as
#include <stdlib.h>
// ...
int *pA = malloc((sizeof *pA) * length);
if ( !pA ) {
// Deal with the failed allocation, maybe exit(1)
}
// ...
free(pA); // <- Don't leak memory!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am writing some code to compute the sum of fibonacci values up to n, as stored in an array. For only certain values of n, I get an error on calling free().
Edit: This code should now compile.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long fib(long *fibs, int n);
int main(int argc, char *argv[]) {
long num, sum;
long n;
long *fibs;
if(argc < 2) {
printf("Usage %s n\n", argv[0]);
exit(EXIT_SUCCESS);
}
n = strtol(argv[1], NULL, 10);
printf("%ld\n", n);
printf("--Allocating memory\n");
fibs = (long *) malloc(sizeof(long) * n);
printf("--Memory allocated\n");
fibs[0] = 1;
fibs[1] = 1;
sum = 0;
for(int i = 0; i <= n; i++) {
num = fib(fibs, i);
sum += num;
printf("%ld\n", num);
}
printf("%ld\n", sum);
printf("--Freeing memory\n");
free(fibs);
printf("--Memory freed\n");
}
long fib(long *fibs, int n) {
if((n == 0) || (n == 1)) {
return 1;
}
fibs[n] = fibs[n - 1] + fibs[n - 2];
return fibs[n];
}
For instance, when I call the program ./fibsum with n=5, I get a core dump.
The lines
fibs[n] = 1;
and
fibs[n] = fibs[n - 1] + fibs[n - 2];
modify memory beyond the legal range. The legal range is fibs[0] - fibs[n-1]. Due to that, the program displays undefined behavior. In your case, the undefined behavior manifests in the form of problem in the call to free.
You may want to allocate one more element than you are currently allocating. Instead of
fibs = (long *) malloc(n * sizeof(n));
use
fibs = malloc((n+1) * sizeof(n));
See an SO post on why you should not cast the return value of malloc.
Like i told you in the comments, you are overflowing when using <= instead of < in the loop. Take a look at the following example, this is by no means trying to be a "cleaned up" version of your code, I just made it work without changing too much.
#include <stdio.h>
#include <stdlib.h>
int number = 300;
long* fib(long* fibs, int n)
{
if (n == 0 || n == 1)
{
fibs[n] = 1;
}
else
{
fibs[n] = (fibs[n-1] + fibs[n-2]);
}
return fibs;
}
int main(int argc, char *argv[])
{
long* fibs = (long*)malloc(number * sizeof(long));
long sum = 0;
for (int i = 0; i < number; ++i) //changed <= to < like i said in the comments
{
sum += fib(fibs, i)[i];
printf("%d\n", sum);
}
printf("\n\nSum of everything: %ld\n", sum);
free(fibs); //no problem
return 0;
}
There are number of problems -
i is undeclared in main.
n is not declared in main.
And most important one this loop-
for(i = 0; i <= n; i++)
As you allocate memory for n items but loop goes from 0 to n .You forgot it should be till n-1 .Thus behaviour is undefined.
As case you described (n=5 so loop should be from 0 to 4).
There are few problems in your code, some are typing mistake I guess, some are logical problem:
You forgot to type n and i
Never cast malloc, so instead of fibs = (long *) malloc(n * sizeof(n)); try fibs = malloc(n * sizeof(long));
In the for loop, instead of for(i = 0; i <= n; i++) use for(i = 0; i < n; i++)
sum += fib(fibs, i); here, sum is long but fib() returns long *, so change function defalcation long *fib(long *fibs, int n) to long fib(long *fibs, int n)
I update your code then run and get output : 12.
The modified code:
#include <stdio.h>
#include <stdlib.h>
long fib(long *fibs, int n) {
if((n == 0) || (n == 1)) {
fibs[n] = 1;
} else {
fibs[n] = fibs[n - 1] + fibs[n - 2];
}
return fibs[n];
}
int main(int argc, char *argv[]) {
long *fibs;
long sum = 0;
int n = 6, i;
fibs = malloc(n * sizeof(long));
long tem;
for(i = 0; i < n; i++) {
tem = fib(fibs, i);
sum += tem;
}
printf("%ld\n", sum);
free(fibs);
}
I've found useful answers on other people's questions countless times here on stackoverflow, but this is my first time asking a question of my own.
I have a C function that dynamically needs to allocate space for an array of structs and then fill the struct members of each array element with values pulled from a file. The member assignment works fine on the first pass of the loop, but I get a segmentation fault on the second pass.
I've written up this quick program illustrating the essentials of the problem I'm having:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int a;
int b;
} myStruct;
void getData(int* count, myStruct** data) {
*count = 5;
*data = malloc(*count * sizeof(myStruct));
int i;
for (i = 0; i < *count; i++) {
data[i]->a = i;
data[i]->b = i * 2;
printf("%d.a: %d\n", i, data[i]->a);
printf("%d.b: %d\n", i, data[i]->b);
}
}
int main() {
int count;
myStruct* data;
getData(&count, &data);
return 0;
}
The output I get from this is:
0.a: 0
0.b: 0
Segmentation fault
I'm not sure where my problem lies. It seems as though the malloc call is only allocating enough space for one struct when it should be allocating space for five.
Any help would be very much appreciated.
The error is here:
for (i = 0; i < *count; i++) {
data[i]->a = i;
data[i]->b = i * 2;
printf("%d.a: %d\n", i, data[i]->a);
printf("%d.b: %d\n", i, data[i]->b);
}
you should do this:
for (i = 0; i < *count; i++) {
(*data)[i].a = i;
(*data)[i].b = i * 2;
printf("%d.a: %d\n", i, (*data)[i].a);
printf("%d.b: %d\n", i, (*data)[i].b);
}
The reason is that you are indexing the wrong "dimension" of data.