As I ask how can I read values from the memory which was put into a memory block by malloc/realloc?
I have a program which creates 2 memory blocks at first and extends until reach 32.Its working fine but in order not to lose values after realloc I start my scanf session with an integer called koru.Koru starts with 0 at the beginning and in every realloc I make its number half of the total amount of memory so I expect not to lose the values entered before realloc sessions but now I need to read what I wrote the memory so I will be sure that I didnt overwrite how can I do that ?
#include "stdio.h"
#include "stdlib.h"
int main()
{
int size=2;
int* p1;
int* p2;
int n;
p1=(int *)malloc((size*sizeof(int)));
int b=0;
int i=0;
int koru=0;
while(size<32)
{
if(i<size){
for(i=koru;i<size;i++)
{
printf("\nEnter value:");
scanf("%d",p1);
}
}
else if(boyut=i)
{
size=size*2;
p2 = (int*) realloc (p1,size*sizeof(int));
p1=p2;
koru=size/2;
printf("\nNOt enough size we make it %d also we protect %d that amount of memory"size,koru);
}
}
return 0;
}
I thought putting a array[i]=p1; and reading it after while loop will solve the problem but later I figured out that its cheating I am not reading from the memory block just reading from another array so this wont work too can somebody lead the way for me please ?
What my program does:
2 blocks memory malloc
takes values and fills it
When it fills improves the memory size multiplying by 2 realloc
starts reading from half number so it dont rewite
continues this progress until it reaches 32
Edit:Simplified question:
I put lots of values in the memory after while loop how can I read them ?
I tried to read it like this but all I get is 0
int counter =0;
while (counter<koru)
{
printf("\n%d",p1[counter]);
counter++;
}
return 0;
}
The correct code which creates a memory block with malloc and extends it with realloc after 32 it exits while loop and writes everything from the p1 pointer(from memory) thanks for help.
Working Code below:
#include "stdio.h"
#include "stdlib.h"
int main()
{
int boyut=2;
int* p1;
int* p2;
int n;
p1=(int *)malloc((boyut*sizeof(int)));
int b=0;
int i=0;
int koru=0;
while(boyut<16)
{
if(i<boyut){
for(i=koru;i<boyut;i++){
printf("\nDeğer Girin:");
scanf("%d", &p1[i]);
}
}
else if(boyut=i)
{
boyut=boyut*2;
p2 = (int*) realloc (p1,boyut*sizeof(int));
p1=p2;
koru=boyut/2;
printf("\nBoyut yetersiz yeni boyutu %d yapıyoruz önceki %d kadar alanı korumaya aldık",boyut,koru);
}
}
int counter =0;
while (counter<koru)
{
printf("\n%d",p1[counter]);
counter++;
}
return 0;
}
I'm not sure exactly what you are asking here, but to access the values in the memory, just use p1 as an array. p1[3] would give you the 4th integer in the memory block.
Just be sure to respect the array bounds.
Bonus problem: you're not even filling the array, you're overwriting the first element each time you input.
The simple solution is to remove p2 entirely and treat p1 as an array:
...
scanf("%d", &p1[i]);
...
Then to read:
int n;
for (n=0; n<i; n++)
printf("%d ", p1[n]);
However, if you want to do it with two pointers instead of array indexing, you need one pointer to track the whole array for malloc and realloc, and the other to track where the current value is for reading/writing.
Initially the array is empty, so they are the same:
p1 = (int *)malloc(boyut * sizeof(int));
p2 = p1;
...
Input only uses the read/write pointer, and increments it each time:
...
scanf("%d", p2++);
...
Memory management only uses the "base" pointer
...
p1 = (int *)realloc(p1, boyut * sizeof(int));
...
(note you should strictly use a temporary variable for the return value of realloc() to check for failure, otherwise you could lose the value of p1)
Then to read we reset the read/write pointer to the start, and iterate through:
int n;
p2 = p1;
for (n=0; n<i; n++)
printf("%d ", *p2++);
Related
I have made the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * convertToBinary(int baseTenNumber)
{
int counter = 0;
char *result = NULL;
int remainder = baseTenNumber;
while(remainder)
{
result = (char *) realloc(result, sizeof(char) + 2);
printf("%d\n", baseTenNumber);
result[counter] = baseTenNumber%2;
remainder/=2;
counter++;
}
return result;
}
int main (void)
{
int input = -1;
while(input)
{
printf("Enter an integer: ");
scanf("%d", &input);
char * result = convertToBinary(input);
printf("The binary version of %d is %s\n", input, result);
memset(result, '0', sizeof(result));
free(result);
}
return 0;
}
Yes, I know the binaries will be written backwards, I will get to that later.
But why doesn't this program save my values?
I am trying to allocate memory on each iteration of the loop. I am not interested in doing it all in one go.
Any hints would be great, thanks!
There's a few ways to get an exact memory fit in C.
One is to precalculate exactly how much memory you need, which you could probably do here. But that's not always possible, and it's more code to write, and more bugs, and more runtime.
Another is to use realloc. Reallocating can get messy and expensive and it's a great way to invite bugs. Sometimes its necessary if you're working with an existing hunk of memory, like growing an array.
The other is to allocate a stack buffer large enough to hold any possible value, then use strdup to copy it to exactly the right amount of heap memory. This is great when you need to process something all at once and you're not sure how big it might be. For example, reading from a file.
// Allocate a big, reusable buffer
char line[BUFSIZ];
while( fgets(line, sizeof(line), fp) ){
...now you can slice and dice line...
}
We can do the same thing for your problem.
#include <stdio.h>
#include <string.h>
// The largest possible string to hold a binary integer
#define BINARY_INT_SIZE ((sizeof(int)*8) + 1)
// A cheap way to convert from integer 0/1 to char 0/1
const char BINARY_TO_CHAR[] = {'0', '1'};
char * convertToBinary(int number) {
// Initialize the stack variable to hold the conversion
char result[BINARY_INT_SIZE] = {0};
for( int counter = 0; number; counter++ ) {
printf("%d %d %d\n", counter, number, number % 2);
result[counter] = BINARY_TO_CHAR[number % 2];
number/=2;
}
// Copy from the stack into exactly enough heap memory
return strdup(result);
}
Stack memory is cheap and fast to allocate and discard. Much faster than reallocating heap memory over and over again in a loop. Using strdup guarantees the persisting heap memory is compact.
Just adding to the wonderful answers already presented, but I wanted to clarify some things no one explicitly stated, just to be safe.
For starters, your values are being saved (though not the correct amount, not in the right locations, and not the right values, I'll explain that later). Your printf() statement simply isn't recognizing the values stored in each index of the array you have made. In your format string, you are using the %s format specifier. This would be okay if you were actually printing a human-readable ASCII code. The problem is you are printing the literal values 0 and 1, which map to "NULL" and "Start of heading", respectively.
The other answers have very good suggestions for how to map the numeric values to the ASCII values, but in theory, if you wanted to print the the indexes in your array as-is, you would need to print in the following way:
printf("The binary version of %d is ", input);
for(int i = numDigits - 1; i >= 0; --i)
printf("%d", result[i]);
In this case, you are printing each item in the array as numbers as opposed to characters.
The next thing I want to point out is your logic in the while loop. Your assignment to result[counter] is always baseTenNum % 2, so it would either store all 0s or all 1s depending on whether the number is always even or odd. Then on top of that, your realloc() is always resizing to a fixed size, as opposed to growing with each new character (as pointed out in another answer :-)).
Hope these help clarify some of your troubles!
Schwerm's answer is the best.
If you want to allocate memory on each iteration, realloc(result, counter + 2) will allocate one more byte as counter increases. The +2 provides a byte for the current character and one for the terminator.
To get the 1 and 0 from the modulus operation into characters that can be printed, add '0'.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * convertToBinary(unsigned int baseTenNumber)
{
int counter = 0;
char *result = NULL;
char *temp = NULL;
int remainder = baseTenNumber;
while(remainder)
{
if ( NULL == ( temp = realloc(result, counter + 2))) {
fprintf ( stderr, "problem realloc\n");
exit ( 0);
}
result = temp;
printf("%d\n", remainder);
result[counter] = remainder%2 + '0';
remainder/=2;
counter++;
}
result[counter] = 0;//terminate
return result;
}
int main (void)
{
unsigned int input = 0;
do
{
printf("Enter an integer: ");
scanf("%u", &input);
if ( input) {
char * result = convertToBinary(input);
printf("The binary version of %d is %s\n", input, result);
free(result);
}
} while(input);
return 0;
}
I got and error which says
Debug assertation failed and heat corruption detected
like everything is working good in my program but I get that error. Where is the memory leak here? I have to free that memory in the main because my functions need to return pointers.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *dynamic_reader(unsigned int n) {
/*making new array and checking if allocation succeeded*/
int *mem;
mem = malloc(n * sizeof(int));
if (!mem) {
printf("Memory allocation failed\n");
exit(-1);
}
/*letting the user to input the values for the array*/
int i = 0;
while (i < n) {
scanf("\n%d", &mem[i]);
i++;
}
/*printing the array just to make sure everything is good*/
for (int j = 0; j < n; j++) {
printf("%d ", mem[j]);
}
return mem;
}
int *insert_into_array(int *arr, unsigned int num, int newval) {
/*making new bigger array*/
int *newarr = realloc(arr, (num + 1) * sizeof(int));
/*adding the integer to this new array */
newarr[num] = newval;
printf("\n");
/*printing to make sure everything is correct*/
for (int j = 0; j < num + 1; j++) {
printf("%d ", newarr[j]);
}
return newarr;
}
int main(void) {
/*In dynamic_reader function I need to make an array which size is given as a parameter*/
/*In this case I choosed 3*/
int *arr = dynamic_reader(3);
int num = 3;
/*In insert_into_array function I need to add one integer to this array I made in dynamic_reader*/
/*The parameters are the array, the number of elements in the array already done and the integer I want to add*/
int *c = insert_into_array(arr, num, 9);
/*I free the memory here because I need to return the pointers of these arrays in the function so it cant be done there*/
free(arr);
free(c);
}
You are double freeing your memory. Check the documentation for realloc. Realloc will either 1) expand the passed buffer or 2) will allocate a new buffer, copy the data, and free the original buffer. When you do:
free(arr);
free(c);
You are double freeing a value that was either once already freed by realloc or already freed by the first free(arr)
Additionally, you should check if realloc fails (returns NULL) and if so, handle the case appropriately.
First you malloc an array, which you return to your main function as arr. Then in another function, you realloc where arr is an argument to the realloc, but some other pointer stores the results. Depending on what happened in realloc, you've either got arr and newarr pointing to the same location, or newarr pointing to a valid location and arr pointing to an invalid location that has been freed. Either way, freeing both of them at the end is a problem.
No need to free(arr), that is taken care of when you realloc() it. The pointer returned by realloc() will either point to memory which includes the original memory, or free the old memory after copying its content to a new, larger chunk of memory.
There are a lot of questions about converting a 2D array into a 1D array, but I am attempting just the opposite. I'm trying to partition a string into substrings of constant length and house them in a 2D array. Each row of this 2D matrix should contain a substring of the initial string, and, if each row were to be read in succession and concatenated, the initial string should be reproduced.
I nearly have it working, but for some reason I am losing the first substring (partitions[0] -- length 8*blockSize) of the initial string (bin):
int main (void){
char* bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
int blockSize = 2; // block size in bytes
int numBlocks = strlen(bin)/(8*blockSize); // number of block to analyze
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); // break text into block
for(int i = 0; i<numBlocks;++i){
partitions[i] = (char*)malloc((8*blockSize+1)*sizeof(char));
memcpy(partitions[i],&bin[8*i*blockSize],8*blockSize);
partitions[i][8*blockSize] = '\0';
printf("Printing partitions[%d]: %s\n", i, partitions[i]);
}
for(int j=0; j<numBlocks;++j)
printf("Printing partitions[%d]: %s\n", j,partitions[j]);
return 0;
}
The output is as follows:
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
Printing partitions[0]: Hj
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
The construction of partitions in the first for loop is successful. After construction at read out, the string at partitions[0] contains garbage values. Can anyone offer some insight?
int numBlocks = strlen(bin)/(8*blockSize); // number of block to analyze
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); // break text into block
for(int i = 0; i<numBlocks;++i){
partitions[i] = (char*)malloc((8*blockSize+1)*sizeof(char));
memcpy(partitions[i],&bin[8*i*blockSize],8*blockSize);
partitions[i][8*blockSize] = '\0';
printf("Printing partitions[%d]: %s\n", i, partitions[i]);
}
This all looks suspicious to me; it's far too complex for the task, making it a prime suspect for errors.
For reasons explained in answers to this question, void * pointers which are returned by malloc and other functions shouldn't be casted.
There's no need to multiply by 1 (sizeof (char) is always 1 in C). In fact, in your first call to malloc you should be multiplying by sizeof (char *) (or better yet, sizeof *partitions, as in the example below), since that's the size of the type of element that partitions points at.
malloc might return NULL, resulting in undefined behaviour when you attempt to assign into the location it points at.
Anything else (i.e. everything that isn't NULL) that malloc, calloc or realloc returns will need to be freed when no longer in use, or else tools such as valgrind (a leak detection program, useful for people who habitually forget to free allocated objects and thus cause memory leaks) will report false positives and lose part of their usefulness.
numBlocks, i, or anything else that's for counting elements of an array, should be declared as a size_t to follow standard convention (e.g. check the strlen manual, synopsis section to see how strlen is declared, noting the type of the return value is size_t). Negative values caused by overflows here will obviously cause the program to misbehave.
I gather you've yet to think about any excess beyond the last group of 8 characters... This shouldn't be difficult to incorporate.
I suggest using a single allocation, such as:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCK_SIZE 8
int main(void) {
char const *bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
size_t bin_length = strlen(bin),
block_count = (bin_length / BLOCK_SIZE)
+ (bin_length % BLOCK_SIZE > 0); // excess as per point 6 above
char (*block)[BLOCK_SIZE + 1] = malloc(block_count * sizeof *block);
if (!block) { exit(EXIT_FAILURE); }
for (size_t x = 0; x < block_count; x++) {
snprintf(block[x], BLOCK_SIZE + 1, "%s", bin + x * BLOCK_SIZE);
printf("Printing partitions[%zu]: %s\n", x, block[x]);
}
for (size_t x = 0; x < block_count; x++) {
printf("Printing partitions[%zu]: %s\n", x, block[x]);
}
free(block);
exit(0);
}
Their are a few problems with your code.
You are allocating **partitions incorrectly.
Instead of:
char** partitions = (char**)malloc((numBlocks+1)*sizeof(char)); /* dont need +1, as numblocks is enough space. */
You need to allocate space for char* pointers, not char characters.
instead, this needs to be:
char** partitions = malloc((numBlocks+1)*sizeof(char*));
Also read Why not to cast result of malloc(), as it is not needed in C.
malloc() needs to be checked everytime, as it can return NULL when unsuccessful.
Once finished with the space allocated, it is always good to free() memory previously requested by malloc(). It is important to do this at some point in the program.
Here is some code which shows this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKSIZE 2
#define BLOCK_MULTIPLIER 8
int main(void) {
const char *bin = "00011101010000100001111101001101000010110000111100000010000111110100111100010011010011100011110000011010";
const size_t blocksize = BLOCKSIZE;
const size_t multiplier = BLOCK_MULTIPLIER;
const size_t numblocks = strlen(bin)/(multiplier * blocksize);
const size_t numbytes = multiplier * blocksize;
char **partitions = malloc(numblocks * sizeof(*partitions));
if (partitions == NULL) {
printf("Cannot allocate %zu spaces\n", numblocks);
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < numblocks; i++) {
partitions[i] = malloc(numbytes+1);
if (partitions[i] == NULL) {
printf("Cannot allocate %zu bytes for pointer\n", numbytes+1);
exit(EXIT_FAILURE);
}
memcpy(partitions[i], &bin[numbytes * i], numbytes);
partitions[i][numbytes] = '\0';
printf("Printing partitions[%zu]: %s\n", i, partitions[i]);
}
printf("\n");
for(size_t j = 0; j < numblocks; j++) {
printf("Printing partitions[%zu]: %s\n", j,partitions[j]);
free(partitions[j]);
partitions[j] = NULL;
}
free(partitions);
partitions = NULL;
return 0;
}
Which outputs non-garbage values:
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
Printing partitions[0]: 0001110101000010
Printing partitions[1]: 0001111101001101
Printing partitions[2]: 0000101100001111
Printing partitions[3]: 0000001000011111
Printing partitions[4]: 0100111100010011
Printing partitions[5]: 0100111000111100
The code is an implementation of the Gift Wrapping Algorithm. The input file is of the form 'X Y Z' on each line, and I don't need to consider the Z co-ordinate. The code works fine for smaller N like 100000 but gives segmentation fault for larger N value. Can some one explain me the reason for it?
#include <stdio.h>
#include <stdlib.h>
#define N 200000
struct Point{
double x,y;
};struct Point p[N];
int ori(struct Point p1, struct Point p2, struct Point p3);
int main(){
FILE *fp,*fp2;
fp2=fopen("out.txt","w");
int i=0;
fp=fopen("sample.txt","r");
if(fp==NULL){
printf("File not found!\n");
exit(0);
}
double g;
for(i=0;i<N;i++)
fscanf(fp,"%lf %lf %lf",&p[i].x,&p[i].y,&g);
int l=0;
for(i=1;i<N;i++){
if(p[i].x<p[l].x){
l=i;
}
}
int base=l,q;
int chullin[N];
for(i=0;i<N;i++)
chullin[i]=-1;
while(true){
q=(base+1)%N;
for(i=0;i<N;i++)
if(ori(p[base],p[i],p[q])==1)
q=i;
chullin[base]=q;
base=q;
if(base==l)
break;
}
int cnt=0;
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i;
fprintf(fp2,"%f %f %d\n",p[i].x,p[i].y,i);
cnt++;
}
return 0;
}
int ori(struct Point p1, struct Point p2, struct Point p3){
int val=p1.x*(p2.y-p3.y)-p1.y*(p2.x-p3.x)+(p2.x*p3.y-p3.x*p2.y);
if(val==0)
return 0;
if(val>0)
return 1;
else return -1;
}
you are totally overflowing the int array 'a' or at least accessing non-existent values within the array, which is on the stack... if chullin[i] != -1 for more than 26 points... or if chullin[i] where i>25, you are writing randoms on the stack.
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i; //problem here.
fprintf(fp2,"%f %f %d\n",p[i].x,p[i].y,i);
cnt++;
}
The problem is not in the array p, but in the array chullin. Try to dynamically allocate the array, using the malloc function:
int *chullin = (int*)malloc(sizeof(int)*N);
// do whatever you want with chullin
free(chullin);
Edit: I will try to explain the cause of the Segmentation fault. When you create a non-dynamic array inside a function, it is allocated in the heap. The heap has limited size, so when you declare a large array, the heap overflows. When you use malloc, you dynamically allocate the array, which means that it is allocated in the stack. The stack has much bigger size than the heap, so you are able to create larger arrays. Global arrays are also allocated in the stack, that's why you needn't allocate them dynamically...
Edit[2]: Array a has size 26, which means that when N is larger than or equal to 26 you will be accessing invalid memory locations, causing segmentation fault.
So I wrote this code but it gives me the same answer everytime. I am increasing the memory allocated to the pointer in steps of 4 and then print the value.
#include <stdio.h>
int main(void) {
int n=0;
char *name = "hello";
scanf("%d",&n);
for(int i =0; i<n;i++){
name += sizeof(int);
printf("%d \n", (sizeof(&name)));
}
return 0;
}
can someone help me? I don't know whats wrong here. I don't need a different code, I just want to understand what's wrong with this.
Try the following, error checking was left out for clarity:
#include <stdio.h>
int main(void)
{
int n=0;
char *name = null;
scanf("%d",&n);
for(int i=0; i<n;i++)
{
char *buffer = null;
//allocate/reallocate the buffer. increases by 4 bytes every iteration
buffer = (char*) realloc(name, (i+1)*4);
name = buffer;
printf("%d \n", (sizeof(&name)));
}
//release the memory used by the buffer
free(name);
return 0;
}
Here are some explanations of what is happening.
#include <stdio.h>
int main(void) {
int n=0;
// this does not actually allocate any memory. It sets the POINTER name to point (like an arrow) to a read-only block that contains "hello"
char *name = "hello";
// string literals generally come in fixed read-only memory
scanf("%d",&n);
for(int i =0; i<n;i++){
// this causes the pointer memory address to be incremented by sizeof(int) (typically 4)
// after the first increment if it will point to a string "o" (incremented by 4 characters)
// after the second increment it will point to some undefined memory behind "hello" in your virtual address space and will have undefined behaviour when accessed
name += sizeof(int);
// sizeof(&name) will give you the size of a char **. Pointer to a character pointer.
// Wich is the same size as all pointers.
// = sizeof(void *) = 8 for 64-bit systems, 4 for 32-bit systems
printf("%d \n", (sizeof(&name)));
}
return 0;
}
This is the way to do it:
#include <stdio.h>
int main(void) {
int n=0;
// allocate 10 bytes of memory and assign that memory address to name
char *name = malloc(10);
// the size of that memory needs to be kept in a separate variable
size_t name_length = 10;
// copy the desired contents into that memory
memcpy(name, "hello", sizeof("hello"));
scanf("%d",&n);
for(int i =0; i<n;i++){
// reallocate the memory into something with sizeof(int) more bytes
void * tmp = realloc(name, name_length += sizeof(int));
// this can fail
if (tmp) {
name = tmp;
} else {
perror("realloc");
exit(-1);
}
printf("%d \n", name_length);
}
return 0;
}
You have not allocated any memory for the pointer at all in the code you provide. You will have to deal with dynamic memory if you want to change the size of the allocated chunk. You will have to initially use malloc and then use realloc to allocate more memory on each step.
Let's step through your code one by one:
char *name = "hello";
this create an array of chars 'h','e','l','l','o',0 and assignes the memory address of the first character to name
for(int i =0; i<n;i++){
name += sizeof(int);
printf("%d \n", (sizeof(&name)));
}
here you add to the name pointer the size of int, which increments this pointer by 4 each pass.
Since this is a char pointer, the pointer is incremented by 4 bytes - since sizeof(int) == 4
You cannot increase the size of your hello char array, since it is not a dynamic array.
If you wish to be able to resize the string, you should malloc and copy the chars to the bigger array.