I attempt to malloc char** to store string, and free this, but I got this error. I can't understand why. The steps are as follows:
1:
char **pid_array = (char **)malloc(sizeof(char *) * MAX_LEN);
2:
pid_array[0] = (char *)malloc(sizeof(char) * SINGLE_LEN * MAX_LEN);
3:
free(pid_array); free(pid_array[0]);
The detailed code follows:
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_LEN 1000
#define SINGLE_LEN 10
int isPid(char *str) {
int len = strlen(str);
for (int i = 0; i < len; i++) {
if (isdigit(str[i]) == 0) {
return 1;
}
}
return 0;
}
void getFileName(char *dir_path, char *pid_array[], int *len) {
DIR *dir = opendir(dir_path);
if (dir == NULL) {
fprintf(stderr, "path open failed!\n");
exit(EXIT_FAILURE);
}
chdir(dir_path);
struct dirent *ent;
int i = 0;
while ((ent = readdir(dir)) != NULL) {
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
continue;
}
int size = strlen(ent->d_name);
if (isPid(ent->d_name) == 0) {
pid_array[i++] = ent->d_name;
}
}
*len = i;
closedir(dir);
}
int main(int argc, char *argv[]) {
int pflag, nflag, vflag;
pflag = 0;
nflag = 0;
vflag = 0;
int opt;
while ((opt = getopt(argc, argv, "pvn")) != -1) {
switch (opt) {
case 'p':
pflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'n':
nflag = 1;
break;
}
}
printf("pflag=%d; nflag=%d; vflag=%d; optind=%d\n", pflag, nflag, vflag, optind);
char **pid_array = (char **)malloc(sizeof(char *) * MAX_LEN);
pid_array[0] = (char *)malloc(sizeof(char) * SINGLE_LEN * MAX_LEN);
for(int i=0; i < MAX_LEN; i++){
pid_array[i]=pid_array[i-1]+SINGLE_LEN;
}
/*
for (int i = 0; i < MAX_LEN; i++) {
pid_array[i] = (char *)malloc(sizeof(char) * SINGLE_LEN);
assert(pid_array[i] != NULL);
}
*/
for (int i = 0; i < MAX_LEN; i++) {
free(pid_array[i]);
}
int *pid_array_len = (int *)malloc(sizeof(int));
getFileName("/proc", pid_array, pid_array_len);
for (int i = 0; i < *pid_array_len; i++) {
printf("%d\n", atoi(pid_array[i]));
}
free(pid_array);
free(pid_array[0]);
free(pid_array_len);
return 0;
}
The error is follow:
error
The steps as noted are not correct.
if pid_array is char** then
*pid_array is char*
**pid_array is char
And you need to construct them as such. And free them in the reverse order. If you intend to have a vector of pointers at pid_array then your case is very very common: every C program gets one for free. The main prototype can be declared as
int main(int argc, char**argv);
The system knows how many char* to pass to the program, but in your case maybe the simplest (safest) way is to use encapsulation and build a block like this
typedef struct
{
size_t argc;
char** argv;
} Block;
I will let an example below.
a way to free the block properly
If you insist in using just the pointer you can easily adapt this. Anyway a possible implementation is
Block* delete (Block* blk)
{
if (blk == NULL) return NULL;
fprintf(
stderr, "Deleting block of %llu strings\n",
blk->argc);
for (int i = 0; i < blk->argc; i += 1)
free(blk->argv[i]);
free(blk->argv);
free(blk);
fprintf(stderr, "Deleted...\n");
return NULL;
}
The reason to return a pointer is to create a simple way to assure the pointer is invalidated as in
my_block = delete (my_block);
In the example
A block is created
is filled with strings of random size
the strings are printed
the block is deleted
main for the example
int main(void)
{
srand(220630);
const int size = MAX_LEN;
Block* my_block = build(size);
fill(my_block);
show(my_block, "a vector of numbered strings");
my_block = delete (my_block);
return 0;
}
the output
a vector of numbered strings
25 strings:
1 "#000#k"
2 "#001#swfsxji"
3 "#002#cn"
4 "#003#akmxhksqgb"
5 "#004#dqnegzryobmhucldx"
6 "#005#iiuqddvuvukkrs"
7 "#006#jxvlsolocgnvgjcrwh"
8 "#007#zylbzumyhmeswxuno"
9 "#008#ex"
10 "#009#ixinxqyxqydnswb"
11 "#010#ylxelydzqgs"
12 "#011#absdfpdjvgwhxcmzekr"
13 "#012#sceqzvmjskkrmszpth"
14 "#013#n"
15 "#014#rsmkrqhssjniqgphjp"
16 "#015#dgojvpflydevwudvv"
17 "#016#qbmaolgrskkqghhkgb"
18 "#017#uzsunopqpdawg"
19 "#018#rvdeaiooylywf"
20 "#019#zfejmgqxu"
21 "#020#fjubcmllylxqahvbfh"
22 "#021#zwanyivra"
23 "#022#vooropiugmuya"
24 "#023#js"
25 "#024#qzecia"
Deleting block of 25 strings
Deleted...
The complete C code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 25
typedef struct
{
size_t argc;
char** argv;
} Block;
Block* build(size_t ttl);
Block* delete (Block* blk);
int fill(Block* bl);
int show(Block* blk, const char* title);
int main(void)
{
srand(220630);
const int size = MAX_LEN;
Block* my_block = build(size);
fill(my_block);
show(my_block, "a vector of numbered strings");
my_block = delete (my_block);
return 0;
}
Block* build(size_t ttl)
{
if (ttl == 0) return NULL;
Block* blk = (Block*)malloc(sizeof(Block));
if (blk == NULL) return NULL;
blk->argc = (ttl > MAX_LEN) ? MAX_LEN : ttl;
blk->argv = (char**)malloc(ttl * sizeof(char*));
if (blk->argv == NULL) return NULL;
for (int i = 0; i < ttl; i += 1)
*(blk->argv + i) = NULL;
return blk;
}
int fill(Block* bl)
{
const char prefix[] = "#nnn#"; // common prefix
char buffer[30] = {0};
char data[20] = {0};
for (int i = 0; i < bl->argc; i += 1)
{
int rest = 1 + rand() % 19;
for (int j = 0; j < rest; j += 1)
data[j] = 'a' + rand() % 26; // a single letter
data[rest] = 0; // terminates string
int res = sprintf(buffer, "#%03d#%s", i, data);
bl->argv[i] = (char*)malloc(strlen(buffer) + 1);
strcpy(bl->argv[i], buffer);
}
return 0;
}
int show(Block* blk, const char* title)
{
if (title != NULL) printf("%s\n", title);
printf("%llu strings:\n", blk->argc);
for (int i = 0; i < MAX_LEN; i += 1)
printf("%d\t \"%s\"\n", 1 + i, *(blk->argv + i));
printf("\n");
return 0;
}
Block* delete (Block* blk)
{
if (blk == NULL) return NULL;
fprintf(
stderr, "Deleting block of %llu strings\n",
blk->argc);
for (int i = 0; i < blk->argc; i += 1)
free(blk->argv[i]);
free(blk->argv);
free(blk);
fprintf(stderr, "Deleted...\n");
return NULL;
}
// https://stackoverflow.com/questions/72809939/
// how-do-i-use-free-properly-to-free-memory-when
// -using-malloc-for-char
I'm allocating memory for my int *occurrences int *wordCounts and char **uniqueWords pointers and then at the end of the function that allocates the memory, i free them. However, when i compile the program i get an double free or corruption (!prev) aborting error. Is it caused by malloc,free or could it be due to how i initialize them inside the for loop ?
PS: I'm talking about the sortedCount() method, located towards the end
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAX_STRING_SIZE 512 /* each line in the file can have up to 512 chars */
void populateWordsArray(int);
void reverse(int);
void first(int);
void middle(int);
void last(int);
int count(int, char*, int);
void sortedCount(int);
void determineUniqueWords(int *,char **, int);
void *malloc_or_end(size_t);
void* malloc_or_end(size_t sz) {
void *pointer;
pointer = malloc(sz);
if(pointer == NULL) {
printf("Out of memory, terminating.\n");
exit(-1);
}
return pointer;
}
/* turn into local */
FILE *file;
char **wordList;
void determineUniqueWords(int *occurrences, char **word, int N) {
int i = 0;
int j = 0;
for(i = 0; i < N; i++) {
if(occurrences[i] < 1) {
continue;
}
for(j = i + 1; j < N; j++) {
if(occurrences[j] == 1 && (strcmp(word[i],word[j])) == 0) {
occurrences[i]++;
occurrences[j] = 0;
}
}
}
}
/**
* Function populateWordsArray: reads N words from
* the given file and populates the wordList array with them.
* Has one argument: int N - the number of words to read.
* */
void populateWordsArray(int N) {
int i = 0;
while(i < N && (fscanf(file,"%s",wordList[i]) == 1)) { /* fscanf returns the number of successfully read items. If it's not 1, the read failed. Same as checking if fscanf reads the eof char. */
i++;
}
}
/**
* Function reverse: prints the words of the
* text file in reverse order.
* */
void reverse(int N) {
int i = 0;
for(i = N-1; i >= 0; i--) {
if(i == 0) {
printf("%s \n",wordList[i]);
} else if(strcmp(wordList[i],"") == 0) { /* improve this in main-> memory allocation */
continue;
}else {
printf("%s ",wordList[i]);
}
}
return;
}
/**
* Function first: Prints the first char of each
* word in the file.
* */
void first(int N) {
char firstChar;
int i = 0;
for(i = 0; i < N; i++) {
firstChar = *wordList[i];
printf("%c",firstChar);
}
printf("\n");
return;
}
/**
* Function middle: Prints the middle char of each word
* from the given file.
* */
void middle(int N) {
int middleIndex = 0;
int i = 0;
char midChar;
for(i = 0; i < N; i++) {
if((strlen(wordList[i]) % 2) == 0) { /* artios */
middleIndex = ((strlen(wordList[i]) / 2) - 1);
midChar = wordList[i][middleIndex];
}
else { /* peritos */
middleIndex = (int) ceil((strlen(wordList[i]) / 2));
midChar = wordList[i][middleIndex];
}
printf("%c",midChar);
}
printf("\n");
return;
}
/**
* Function last: Prints the last char of each
* word from the given file.
* */
void last(int N) {
int i = 0;
char lastChar;
int lastPos;
for(i = 0; i < N; i++) {
lastPos = strlen(wordList[i]) - 1;
lastChar = wordList[i][lastPos];
printf("%c",lastChar);
}
printf("\n");
return;
}
/**
* Function count: Prints the number of times
* that the selected word is found inside the N first words
* of the file.
* */
int count(int N, char *word, int callID) {
int i = 0;
int count = 0;
for(i = 0; i < N; i++) {
if(strcmp(word,wordList[i]) == 0) {
count++;
}
}
if(callID == 0) { /* if callID == 0 (main called count and we want the output) */
printf("%d",count);
printf("\n");
}
return count;
}
void sortedCount(int N) {
int i,j = 0;
int *occurrences;
int *wordCounts;
char **uniqueWords;
/* mem allocation */
uniqueWords = malloc_or_end(N * sizeof(char*)); /* worst case: every word is unique */
wordCounts = malloc_or_end(N * sizeof(int));
occurrences = malloc_or_end(N * sizeof(int));
/* initialize rootWord and occurrences for the "each word is unique and occurs only once" scenario */
for(i = 0; i < N; i++) {
uniqueWords[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
occurrences[i] = 1;
}
determineUniqueWords(occurrences,wordList,N);
/* populate the wordCounts & uniqueWords "arrays" with the appropriate data in order to sort them successfully */
for(i = 0; i < N; i++) {
if(occurrences[i] > 0) {
wordCounts[i] = count(N,wordList[i],1);
uniqueWords[i] = wordList[i];
}
}
for(i = 0; i < N; i++) {
free(uniqueWords[i]);
}
free(uniqueWords);
free(occurrences);
free(wordCounts);
return;
}
int main(int argc,char *argv[]) { /* argv[1] = op argv[2] = name argv[3] = <word> */
int N = -1;
int i = 0;
int spaceNum,nlNum = -1;
file = fopen(argv[2],"r");
if(file == (FILE *) NULL) { /* check if the file opened successfully */
fprintf(stderr,"Cannot open file\n");
}
fscanf(file,"%d",&N); /* get the N number */
wordList = malloc_or_end(N * sizeof(char *)); /* allocate memory for pointers */
for(i = 0; i < N; i++) {
wordList[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char)); /* allocate memory for strings */
}
populateWordsArray(N);
if(strcmp(argv[1],"-reverse") == 0) {
reverse(N);
} else if(strcmp(argv[1],"-first") == 0) {
first(N);
} else if(strcmp(argv[1],"-middle") == 0) {
middle(N);
} else if(strcmp(argv[1],"-last") == 0) {
last(N);
} else if((strcmp(argv[1],"-count") == 0) && argv[3] != NULL) {
i = count(N,argv[3],0);
} else if((strcmp(argv[1],"-sorted") == 0) && (strcmp(argv[3],"-count") == 0)) {
sortedCount(N);
} else {
/* i only wish i could print something here */
}
/* End of program operations */
for(i = 0; i < N; i++) {
free(wordList[i]);
}
free(wordList);
fclose(file);
return 0;
}
You are overwriting the value of a pointer to heap memory on line 185:
uniqueWords[i] = wordList[i];
This means that when you free it later, you are actually freeing the allocated rows in wordList. Now you have two problems:
When you free the wordList rows on lines 244-246, it will be a double-free
You are losing your reference to the uniqueWords rows.
Use strcpy to assign to a dynamically-allocated string rather than the = operation.
I'm leaking a very small amount of memory in a wf function I'm writing, and I can't seem to exactly locate it. I'm using a hash table to hold freqency, but my testing makes it look like it's not in the hashing functions. Here are my functions to open/read files and free the data at the end. I'm sure it's a simple bug, but I've been looking at this code too long to be able to see it.
typedef struct {
int noInFiles, numFiles, numToPrint;
char** fileNames;
FILE** files;
Hash hash;
} Freq;
void handleInput(int argc, char* argv[], Freq* freq) {
int num = 0, i, j = 0;
char* crap;
printf("memcurrent pre fileName alloc: %d\n\n", memCurrent());
freq->fileNames = calloc(argc - 1, sizeof(char**));
printf("memcurrent post filename alloc: %d\n\n", memCurrent());
freq->numToPrint = 10;
if(argc < 2) {
freq->noInFiles = 1;
freq->numFiles = 0;
return;
}
for(i = 1; i < argc; i++) {
if(argv[i][0] == '-') {
if(argv[i][1] == 'n') {
num = strtol(argv[i] + 2, &crap, 10);
freq->numToPrint = num;
}
else {
fprintf(stderr, "Usage: wf [-nX] [file...]\n");
exit(EXIT_FAILURE);
}
}
else {
freq->fileNames[j] = calloc(strlen(argv[i]) + 1 ,sizeof(char));
strcpy(freq->fileNames[j], argv[i]);
j++;
freq->numFiles++;
}
}
}
void openFiles(Freq* freq) {
int i;
char* str;
printf("Memcurrent pre open: %d\n",memCurrent());
freq->files = calloc(freq->numFiles,sizeof(FILE**));
printf("Memcurrent post open: %d\n",memCurrent());
for(i = 0; i < freq-> numFiles; i++) {
freq->files[i] = fopen(freq->fileNames[i],"r");
if(freq->files[i] == NULL) {
str = malloc(strlen(freq->fileNames[i]) + 5);
sprintf(str,"wf: %s",freq->fileNames[i]);
perror(str);
free(str);
exit(EXIT_FAILURE);
}
}
}
void freeFreq(int argc, Freq* freq) {
int i;
for(i = 0; i < argc - 1 ; i++) {
free(freq->fileNames[i]);
}
free(freq->fileNames);
free(freq->files);
}
Hash functions
typedef struct {
Entry* arr;
int size, numValid;
} Hash;
void initHash(Hash* hash) {
hash->arr = calloc(BASESIZE, sizeof(Entry));
TOTALALLOC =+ (BASESIZE * sizeof(Entry));
hash->size = BASESIZE;
hash->numValid = 0;
}
void freeTable(Hash* hash) {
int i;
for(i = 0; i < hash->numValid - 1; i++) {
if(hash->arr[i].correct == 1 && hash->arr[i].valid == 1) {
wordsFreed++;
free(hash->arr[i].word);
}
}
free(hash->arr);
}
This might be it:
for(i = 0; i < hash->numValid - 1; i++) {
If you have numValid set to 0 at start, I'm presuming that you increment it each time you add an entry to the array.
So if numValid is 1, then you will never loop, which means you will leak one of your entries. It seems that each time you free the hash, you will leak one entry, unless the hash has no entries at all.
This may not fix your problem, but ..
There is a mismatch between the number of allocations and deallocations for freq->fileNames.
Allocation:
else {
freq->fileNames[j] = calloc(strlen(argv[i]) + 1 ,sizeof(char));
strcpy(freq->fileNames[j], argv[i]);
j++;
freq->numFiles++;
}
Deallocation:
for(i = 0; i < argc - 1 ; i++) {
free(freq->fileNames[i]);
}
Assuming the logic for allocation is correct, the logic for deallocation needs to be:
for(i = 0; i < freq->numFiles ; i++) {
free(freq->fileNames[i]);
}
PS
I noticed that you have calls to fopen but no calls to fclose in your posted code.
My code has a memory leak problem. I don't know where I went wrong. Below is the code: I am trying to read from csv file and store a particular columns.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
FILE *result = fopen ("C:\\Users\\pa1rs\\Desktop\\local.csv", "w");
const char *text = "LOA,NAME,";
fprintf (result, "%s", text);
char *token;
char *endToken;
int lines = 0;
char ch; /* should check the result */
FILE *file = fopen ("C:\\Users\\pa1rs\\Desktop\\samplee.csv", "r");
char line[300];
if (file == NULL) {
perror ("Error opening the file");
} else {
while (!feof (file)) {
ch = fgetc (file);
if (ch == '\n') {
lines = lines + 1;
}
}
//printf(" no of lines existing in the file %d\n\n", lines);
}
fseek (file, 0, SEEK_SET);
while ((ch = fgetc (file)) != '\n') {
// we don't need the first line on sample.csv
// as it is just the description part
}
int s[lines - 1];
int j = 0;
char *N[lines - 1];
while (fgets (line, sizeof (line), file)) {
int i = 0;
token = line;
do {
endToken = strchr (token, ',');
if (endToken)
*endToken = '\0';
if (i == 3) {
s[j] = atoi (token);
}
if (i == 12) {
N[j] = (char *) malloc (strlen (token) * sizeof (char));
strcpy (N[j], token);
}
if (endToken)
token = endToken + 1;
i++;
} while (endToken);
j = j + 1;
}
//******************************************************unigue loa
int count = 0;
int g = 0;
int h = 0;
int LOA[lines - 1];
int dd = 0;
for (dd = 0; dd < lines - 1; dd++) {
LOA[dd] = 0;
}
for (g = 0; g < lines - 1; g++) {
for (h = 0; h < count; h++) {
if (s[g] == LOA[h])
break;
}
if (h == count) {
LOA[count] = s[g];
count++;
}
}
int xw = 0;
for (xw = 0; xw < count; xw++) {
//printf("%d \t",LOA[xw]);
}
//printf("LOA Array Length is: %d \n",count);
//********************************************************
////FOR UNIQUE NAMES ARRAY
//printf("No of unique names are %d",county);
//FOR UNIQUE CAUSES ARRAY
char *sa[9] =
{ "Monticello", "Valparaiso", "Crown Point", "Plymouth", "Goshen",
"Gary", "Hammond", "Laporte", "Angola" };
int countz = 0;
int gz = 0;
int hz = 0;
char *LOAz[lines - 1];
int zero2 = 0;
for (zero2 = 0; zero2 < lines - 1; zero2++) {
LOAz[zero2] = NULL;
}
for (gz = 0; gz < lines - 1; gz++) {
for (hz = 0; hz < countz; hz++) {
if (strcmp (N[gz], LOAz[hz]) == 0)
break;
}
if (hz == countz) {
LOAz[countz] = (char *) malloc (strlen (N[gz]) * sizeof (char));
strcpy (LOAz[countz], N[gz]);
countz++;
}
}
int nz = 0;
for (nz = 0; nz < countz; nz++) {
fprintf (result, "%s,", LOAz[nz]);
}
fprintf (result, "\n");
// printf("%d",countz);
//*****************************
int i = 0;
int jjj = 0;
int xxx = 0;
int ggg = 0;
int k = 0;
int kount[count][countz];
for (xxx = 0; xxx < count; xxx++) {
for (ggg = 0; ggg < countz; ggg++) {
kount[xxx][ggg] = 0;
}
}
for (i = 0; i < count; i++) {
for (k = 0; k < countz; k++) {
for (jjj = 0; jjj < lines - 1; jjj++) {
if (LOA[i] == s[jjj]) {
if (strcmp (LOAz[k], N[jjj]) == 0) {
kount[i][k]++;
}
}
}
}
}
int ig = 0;
int ik = 0;
for (ig = 0; ig < count; ig++) {
fprintf (result, "%d,%s", LOA[ig], sa[ig]);
for (ik = 0; ik < countz; ik++) {
fprintf (result, ",%d", kount[ig][ik]);
}
fprintf (result, "\n");
}
int rrr = 0;
free (N);
for (rrr = 0; rrr < lines - 1; rrr++) {
free (LOAz[rrr]);
}
//*****************************
//fclose(result);
fclose (file);
return 0;
}
Lines I got here is 13761 and LOAz was declared with array size lines-1=13761, but unique ones I got here are only 49, So I am reallocating memory for that and remaining are unused , I think problem started there.
Please help! Thanks in Advance.
One problem in your code is that you don't allocate enough memory for strings. For example, in these lines:
N[j] = (char*) malloc(strlen(token) * sizeof(char));
strcpy(N[j], token);
// ...
LOAz[countz] = (char*) malloc(strlen(N[gz]) * sizeof(char));
strcpy(LOAz[countz], N[gz]);
The problem is that strlen returns the number of non-zero symbols in the string. However, to store the string you need one more byte, to also store the zero terminating character, so the buffer size to store s should be at least strlen(s) + 1.
Also, a better coding style is to avoid casting the return value of malloc.
I'm writing program to count scores.
The input file full list.txt looks like:
123456,11,24,,51,,12,,76,,,531,12,,,,24,56,,,,,118,,,,,,,,,,,,,,20,,,,,
123456,11,24,,51,,12,,76,,,531,12,,,,24,56,,,,,118,,,,,,,,,,,,,,20,,,,,
123456,11,24,,51,,12,,76,,,531,12,,,,24,56,,,,,118,,,,,,,,,,,,,,20,,,,,
123456,11,24,,51,,12,,76,,,531,12,,,,24,56,,,,,118,,,,,,,,,,,,,,20,,,,,
...
123456,11,24,,51,,12,,76,,,531,12,,,,24,56,,,,,118,,,,,,,,,,,,,,20,,,,,
The first number is ID, rest are scores. I was trying to put this file to matrix of c[42][1000] to count the total scores and arrange them in increasing order... But the problem I've faced is:
The program only counts the 1st line so far....
Any ideas how to make it store all of them?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int lines_allocated = 1000;
int max_line_len = 150;
double c[42][1000];
char **words = (char **)malloc(sizeof(char*)*lines_allocated);
if (words==NULL)
{
fprintf(stderr,"Out of memory (1).\n");
exit(1);
}
FILE *fp = fopen("full list.txt", "r");
if (fp == NULL)
{
fprintf(stderr,"Error opening file.\n");
exit(2);
}
int i;
for (i=0;1;i++)
{
int j;
if (i >= lines_allocated)
{
int new_size;
new_size = lines_allocated*2;
words = (char **)realloc(words,sizeof(char*)*new_size);
if (words==NULL)
{
fprintf(stderr,"Out of memory.\n");
exit(3);
}
lines_allocated = new_size;
}
words[i] = (char*)malloc(max_line_len);
if (words[i]==NULL)
{
fprintf(stderr,"Out of memory (3).\n");
exit(4);
}
if (fgets(words[i],max_line_len-1,fp)==NULL)
break;
for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--)
;
words[i][j]='\0';
}
int j;
int k=i;
for(j = 0; j < k; j++)
{
printf("%s\n", words[j]);
char *pptr = words[j];
int l;
words[j][strlen(words)-1]=',';
for (l = 0; l < 41; l++)
{
char *ptr = strchr(pptr, ',');
if (ptr)
{
*ptr = 0;
c[l][j] = atof(pptr);
pptr = ptr + 1;
}
}
for (l = 0; l < 41; l++)
{
printf("%.2lf\n", c[l][j]);
}
return 0;
}
for (;i>=0;i--)
free(words[i]);
free(words);
return 0;
}
May be the matrix doesn't store any value at all.
BLUEPIXY, thanks for attention, solved =)
Was extra return 0.
However:
words[j][strlen(words)-1]=',';
or
words[j][strlen(words[j])-1]=',';
Does not affect the matrix. I have no idea why it does not, but it should, shouldn't it?
Final code is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int lines_allocated = 1000;
int max_line_len = 150;
double c[42][1000];
char **words = (char **)malloc(sizeof(char*)*lines_allocated);
if (words==NULL)
{
fprintf(stderr,"Out of memory (1).\n");
exit(1);
}
FILE *fp = fopen("full list.txt", "r");
if (fp == NULL)
{
fprintf(stderr,"Error opening file.\n");
exit(2);
}
int i;
for (i=0;1;i++)
{
int j;
if (i >= lines_allocated)
{
int new_size;
new_size = lines_allocated*2;
words = (char **)realloc(words,sizeof(char*)*new_size);
if (words==NULL)
{
fprintf(stderr,"Out of memory.\n");
exit(3);
}
lines_allocated = new_size;
}
words[i] = (char*)malloc(max_line_len);
if (words[i]==NULL)
{
fprintf(stderr,"Out of memory (3).\n");
exit(4);
}
if (fgets(words[i],max_line_len-1,fp)==NULL)
break;
for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--)
;
words[i][j]='\0';
}
int j;
int k=i;
for(j = 0; j < k; j++)
{
printf("%s\n", words[j]);
char *pptr = words[j];
int l;
words[j][strlen(words)-1]=',';
for (l = 0; l < 42; l++)
{
char *ptr = strchr(pptr, ',');
if (ptr)
{
*ptr = 0;
c[l][j] = atof(pptr);
pptr = ptr + 1;
}
}
}
int l;
for (j = 0; j < k; j++)
{
printf("\n");
for (l = 0; l < 42; l++)
{
printf("%.2lf\t", c[l][j]);
}
}
for (;i>=0;i--)
free(words[i]);
free(words);
return 0;
}
However, now the problem is the value after last comma does not included to array....