Freeing an array of pointer but heap block - global-variables

I wrote a program that has to read a 2D array from a text file and save it into a double pointer which will act as a 2D array.
Here's the code :
#include <stdio.h>
#include <stdlib.h>
char **create_map(char* filename);
int n;
int m;
char **map;
int main(int argc, char* argv[]) {
int i;
map = create_map(argv[1]);
for(i = 0; i < n; i++) {
free(map[i]);
}
free(map);
return 0;
}
char **create_map(char *filename) {
int i = 0;
char *row;
char **map;
FILE *file = fopen(filename, "r");
fscanf(file, "%d %d", &n, &m);
map = malloc(sizeof(char *) * n);
row = malloc(sizeof(char)*m);
while(fscanf(file, "%s\n", row) != EOF) {
map[i] = malloc(sizeof(char)*m);
strcpy(map[i], row);
i++;
}
free(map[9]);
free(row);
fclose(file);
return map;
}
The content of the file is stored successfully in the map variable, but when it comes to freeing some space the debugger prints "warning: Heap block at 0000029967AF5770 modified at 0000029967AF578A past requested size of a".
Why the memory can't be freed?
Where's the error?
Thank you in advance.

Related

Pass array pointer to other program and extract that pointer in c

I am trying to pass an array of integer to other program and accept that from *argv. Then sort the array and print that from initial program. But I can not accept the pointer of the array and work with it. (can't even compile sort.c)
#include<stdio.h>
int main(int argc, char *argv[])
{
int arr = argv[1];
int temp = 0;
int length = sizeof(arr);
//Sort the array in descending order
for (int i = 0; i < length; i++) {
for (int j = i+1; j < length; j++) {
if(arr[i] < arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int length = args-1;
int arr[length];
for(int i=0;i<length,i++)
{
arr[i]=argv[i+1];
}
int *p=arr
pid_t pid=fork();
if (pid==0) {
execv("sort",p);
}
else {
}
return 0;
}

How does one use qsort to sort a char containing pathnames/files based on their bytes?

I basically wrote a code in which I take two command line arguments one being the type of file that I want to search in my directory and they other being the amount I want(which is not implemented yet, but I can fix that)
The code is like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define sizeFileName 500
#define filesMax 5000
int cmpfunc( const void *a, const void *b) {
return *(char*)a + *(char*)b;
}
int main( int argc, char ** argv) {
FILE * fp = popen( "find . -type f", "r");
char * type = argv[1];
char * extension = ".";
char* tExtension;
tExtension = malloc(strlen(type)+1+4);
strcpy(tExtension, extension);
strcat(tExtension, type);
// printf("%s\n",tExtension);
int amount = atoi(argv[2]);
//printf("%d\n",amount);
char buff[sizeFileName];
int nFiles = 0;
char * files[filesMax];
while(fgets(buff,sizeFileName,fp)) {
int leng = strlen(buff) - 1;
if (strncmp(buff + leng - 4, tExtension, 4) == 0){
files[nFiles] = strndup(buff,leng);
//printf("\t%s\n", files[nFiles]);
nFiles ++;
}
}
fclose(fp);
printf("Found %d files\n", nFiles);
long long totalBytes = 0;
struct stat st;
// sorting based on byte size from greatest to least
qsort(files, (size_t) strlen(files), (size_t) sizeof(char), cmpfunc);
for(int i = 0;i< nFiles; i ++) {
if(0!= stat(files[i],&st)){
perror("stat failed:");
exit(-1);
}
totalBytes += st.st_size;
printf("%s : %ld\n",files[i],st.st_size);
}
printf("Total size: %lld\n", totalBytes);
// clean up
for(int i = 0; i < nFiles ; i ++ ) {
free(files[i]);
}
return 0;
}
So far I have every section set up properly, upon running the code say $./find ini 5, it would print out all the ini files followed by their byte size(it's currently ignore the 5). However, for the qsort(), I'm not exactly sure how I would sort the contents of char * files as while it holds the pathnames, I had to use stat to get the byte sizes, how would I print out a sorted version of my print statements featuring the first statement being the most bytes and finishes at the least bytes?
If we suppose your input is valid, your question could be simplified with:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define filesMax 5000
int cmpfunc(const void const *a, const void *b) { return *(char *)a + *(char *)b; }
int main(void) {
int nFiles = 4;
char *files[filesMax] = {"amazing", "hello", "this is a file", "I'm a bad file"};
qsort(files, strlen(files), sizeof(char), cmpfunc);
for (int i = 0; i < nFiles;; i++) {
printf("%s\n", files[i]);
}
}
If you compile with warning that give you:
source_file.c:11:23: warning: incompatible pointer types passing 'char *[5000]' to parameter of type 'const char *' [-Wincompatible-pointer-types]
qsort(files, strlen(files), sizeof(char), cmpfunc);
^~~~~
qsort() expect the size of your array (or in your case a subsize) and it's also expect the size of one element of your array. In both you wrongly give it to it. Also, your compare function doesn't compare anything, you are currently adding the first bytes of both pointer of char, that doesn't make a lot of sense.
To fix your code you must write:
qsort(files, nFiles, sizeof *files, &cmpfunc);
and also fix your compare function:
int cmpfunc_aux(char * const *a, char * const *b) { return strcmp(*a, *b); }
int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }
also size should be of type size_t:
size_t nFiles = 0;
Don't forget that all informations about how to use a function are write in their doc.
how would I print out a sorted version of my print statements featuring the first statement being the most bytes and finishes at the least bytes?
Your code don't show any clue that your are trying to do that, you are currently storing name file and only that. How do you expect sort your file with an information you didn't acquired ?
However, that simple create a struct that contain both file name and size, acquire information needed to sort it and sort it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <inttypes.h>
struct file {
off_t size;
char *name;
};
int cmpfunc_aux(struct file const *a, struct file const *b) {
if (a->size > b->size) {
return -1;
} else if (a->size < b->size) {
return 1;
} else {
return 0;
}
}
int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }
#define filesMax 5000
int main(void) {
size_t nFiles = 4;
struct file files[filesMax] = {{42, "amazing"},
{21, "hello"},
{168, "this is a file"},
{84, "I'm a bad file"}};
qsort(files, nFiles, sizeof *files, &cmpfunc);
for (size_t i = 0; i < nFiles; i++) {
printf("%s, %" PRId64 "\n", files[i].name, (intmax_t)files[i].size);
}
}
The function cmpfunc() provided adds the first character of each string, and that's not a proper comparison function (it should give a opposite sign value when you switch the parameters, e.g. if "a" and "b" are the strings to compare, it adds the first two characters of both strings, giving 97+98 == 195, which is positive on unsigned chars, then calling with "b" and "a" should give a negative number (and it again gives you 98 + 97 == 195), more on, it always gives the same result ---even with signed chars--- so it cannot be used as a sorting comparator)
As you are comparing strings, why not to use the standard library function strcmp(3) which is a valid comparison function? It gives a negative number if first string is less lexicographically than the second, 0 if both are equal, and positive if first is greater lexicographically than the second.
if your function has to check (and sort) by the lenght of the filenames, then you can define it as:
int cmpfunc(char *a, char *b) /* yes, you can define parameters as char * */
{
return strlen(a) - strlen(b);
}
or, first based on file length, then lexicographically:
int cmpfunc(char *a, char *b)
{
int la = strlen(a), lb = strlen(b);
if (la != lb) return la - lb;
/* la == lb, so we must check lexicographycally */
return strcmp(a, b);
}
Now, to continue helping you, I need to know why do you need to sort anything, as you say that you want to search a directory for a file, where does the sorting take place in the problem?

Finding the number of occurence of all the permutations of a SubString in a String in C

Basically this program is made up of two other programs.
First Part to find the permutations of a Sub-String and the
Second Part to find the number of occurence of all the permutations in a given String.
I'm not Getting the required output for most cases
I'd be glad if anybody could help.Thanks.
Here is the Program..
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int appearanceCount(int input1,int input2,char* input3,char* input4)
{
int count=0,temp,i,j,k;
int no_of_permutations=1;
for(i=1;i<input1+1;i++)
{
no_of_permutations *= i;
}
int a = no_of_permutations/((input1-1));
for (i=0; i < a; i++)
{
for(j=0; j<input1-1; j++)
{
char temp;
temp=input3[j];
input3[j]=input3[j+1];
input3[j+1] = temp;
//printf("\n%s",input3);
char *temp_input4 = input4;
//Now I have got the permutation
//Finding the occurance
while(temp_input4 = (strstr(temp_input4, input3)) )
{
count++;
printf("\n%s -- %s -- %d",temp_input4,input3,count);
temp_input4++;
}
}
}
return count;
}
int main()
{
int output = 0;
int ip1;
scanf("%d", &ip1);
int ip2;
scanf("%d", &ip2);
char* ip3;
ip3 = (char *)malloc(512000 * sizeof(char));
scanf("\n%[^\n]",ip3);
char* ip4;
ip4 = (char *)malloc(512000 * sizeof(char));
scanf("\n%[^\n]",ip4);
output = appearanceCount(ip1,ip2,ip3,ip4);
printf("\n%d", output);
return 0;
}
My Expected output for the values
4
11
cAda
AbrAcadAbRa
would be
2
because the two possible sequence that can be found in the string are Acad and cadA
but I get the output as 0;
Try using anagram search and then it will work fine.

How to scatter an entire 2D array to all processes using MPI

As the title suggests I'm looking to take an entire 2D array and scatter that whole array to the other processes. Here is the code I am using:
int main(int argc, char **argv)
{
MPI_Init(&argc,&argv);
int i,j,size,rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (argc!=3)
{
printf("Usage : pairwise numberOfSequences lengthOfSequences\n eg. pairwise 10000 50\n");
exit(0);
}
sscanf(argv[1],"%d",&N);
sscanf(argv[2],"%d",&M);
char strings[N][M+1];
if(rank == 0)
{
for (i=0; i<N; i++)
{
//Here I read from a file into the array strings and this works
scanf("%s\n",strings[i]);
printf("Rank:%d i value:%d # %s\n",rank,i,strings[i]);
}
}
MPI_Barrier(MPI_COMM_WORLD);
char array_for_all[N][M+1];
//I think here my parameters are wrong for Scatter.
MPI_Scatter(strings, N*(M+1),MPI_CHAR,array_for_all, N*(M+1), MPI_CHAR, 0,MPI_COMM_WORLD);
for (i=0; i<N; i++)
{
printf("Rank:%d i value:%d # %s\n",rank,i,array_for_all[i]);
}
I'm not to sure if I am implementing the scatter correctly. I dont want to send parts of the array to each process, I want to send the whole array to each process or is there a better way of doing this?
As signaled by #Wesley , the right way to go is to use MPI_Bcast(), to broadcast the data over all processus. The first argument should be the pointer to the data : &strings[0][0].
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
MPI_Init(&argc,&argv);
int N,M;
int i,j,size,rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (argc!=3)
{
printf("Usage : pairwise numberOfSequences lengthOfSequences\n eg. pairwise 10000 50\n");
exit(0);
}
sscanf(argv[1],"%d",&N);
sscanf(argv[2],"%d",&M);
char strings[N][M+1];
if(rank == 0)
{
for (i=0; i<N; i++)
{
//Here I read from a file into the array strings and this works
scanf("%s",strings[i]);
printf("Rank:%d i value:%d # %s\n",rank,i,strings[i]);fflush(stdout);
}
printf("input over, now output :\n");fflush(stdout);
}
//I think here my parameters are wrong for Scatter.
MPI_Bcast(&strings[0][0],N*(M+1), MPI_CHAR, 0,MPI_COMM_WORLD);
// MPI_Scatter(strings, N*(M+1),MPI_CHAR,array_for_all, N*(M+1), MPI_CHAR, 0,MPI_COMM_WORLD);
for (i=0; i<N; i++)
{
printf("Rank:%d i value:%d # %s\n",rank,i,strings[i]);fflush(stdout);
}
MPI_Finalize();
return 0;
}

How is unsigned int *ptr treated as prt[i]?

int *c;
int d,noofentries;
struct A
{
unsigned int *ptr;
int entry;
}a;
a->ptr=memalloc(34,unsigned int);
a->ptr = (unsigned int*) entry
nofoentries = 8 ;
d =56749;
for(i=0;i<noofentries;i++)
{
c[i] = d; // how is a pointer treated as array ?
}
for(i=0;i<34;i++)
{
a->ptr[i] = c[i]; //segmentation fault occurs
}
I require the assignment of the values populated in c[i] to be assigned to a->ptr[i]. So that when a->ptr[i] deleted then c[i] is also freed.
Kindly help!!
generally you would not want your pointer to be treated as an array, rather you would have an array and use its name as pointer to refer to any particular member of the array
for e.g
int arr[5];
//the array name 'arr' points to the zeroth element
so now you can use *(arr+ indexNo) = value or arr[indexNo] = value, to assign a value to a particular element
you would want to use your pointer as an array, when you have assigned an array to it.
for e.g
int arr[5];
int *ptr;
if you do
ptr = arr;
you can access ptr as you would have accessed arr
as
ptr[index]= value;
a pointer to a type is just the same than an array of the type
*( c + x ) = a
<=>
c[x] = a;
c + x find the right pointer position since it adds x * sizeof(type) to c pointer.
your code compiling under gcc :
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
struct A { unsigned int *ptr; int entry; };
int main(int argc, char ** argv)
{
unsigned int * c;
unsigned int d;
int noofentries, i;
struct A a;
noofentries=34;
c=malloc(noofentries * sizeof(unsigned int));
d =56749;
for(i=0;i<noofentries;i++) { c[i] = d; }
// no need to copy full array c, since ptr is a pointer over it...
a.ptr = c;
// warning if above line is not done then allocation of ptr is required:
// a.ptr = malloc(noofentries * sizeof(unsigned int));
// and content copy
// for(i=0;i<noofentries;i++) { a.ptr[i] = c[i]; }
for(i=0;i<noofentries;i++) {
assert( a.ptr[i] == *(c + i) );
printf("a.ptr[%u]=%u\n",i,*(a.ptr + i));
}
free(c);
}

Resources