C Search for string in heap array - arrays

I use the following code to load a large hashtable on the heap.
However i dont know the right syntax to search the whole array after loading.
I suppose i can add a strcmp in the last J loop??
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int lines_allocated = 128;
int max_line_len = 100;
/* Allocate lines of text */
char **words = (char **)malloc(sizeof(char*)*lines_allocated);
if (words==NULL)
{
fprintf(stderr,"Out of memory (1).\n");
exit(1);
}
FILE *fp = fopen("hashtable.txt", "r");
if (fp == NULL)
{
fprintf(stderr,"Error opening file.\n");
exit(2);
}
int i;
for (i = 0; 1; i++)
{
int j;
/* Have we gone over our line allocation? */
if (i >= lines_allocated)
{
int new_size;
/* Double our allocation and re-allocate */
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;
}
/* Allocate space for the next line */
words[i] = 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;
/* Get rid of CR or LF at end of line */
for (j = strlen(words[i]) - 1; j >= 0 && (words[i][j] == '\n' || words[i][j] == '\r')j--);
words[i][j] = '\0';
}
int j;
for(j = 0; j < i; j++)
printf("%s\n", words[j]);
// Search for a string e.g "ffffffffff999999999922222222227777777777" in words[]
//
//strcmp ( string, words[j])????
//
//
//
/* Good practice to free memory */
for (;i>=0;i--)
free(words[i]);
free(words);
return 0;
}
i have tried to implement strcmp in the loop but then the program segfaults.
Used this example :
/* what is i? the number of items used in the array? */
for(x = 0; x < i; x++) {
if ( strcmp( new_name, names[x] ) == 0 ){
/* match, x is the index */
return x;
}
}
/* here with no match */
return -1;

As i was indenting your code i saw:
for (j = strlen(words[i]) - 1; j >= 0 && (words[i][j] == '\n' || words[i][j] == '\r')j--);
I think you meant:
for (j = strlen(words[i]) - 1; j >= 0 && (words[i][j] == '\n' || words[i][j] == '\r'); j--)
----^^^^^^^
That while would never execute what it had between braces.

You have a problem here:
for (j=strlen(words[i]) - 1; j>=0 && (words[i][j]=='\n' || words[i][j]=='\r'); j--);
words[i][j]='\0';
j is off by one. You shoud increment jjust after the loop:
for (j=strlen(words[i])-1; j>=0 && (words[i][j]=='\n' || words[i][j]=='\r'); j--)
{
}
words[i][j + 1] = '\0';
The extra { } is there only for readibility purposes. Otherwise if you forget the ; after the for, your code will compile correctly but with words[i][j +1 ]='\0'; being part of the loop.
Other off by one problem:
You must decrement i here:
/* Good practice to free memory */
i-- ; // <<<< decrement i here
for (;i>=0;i--)
free(words[i]);
Problem with strcmp:
Concerning your strcmp problem you probably want this:
int j;
for(j = 0; j < i; j++)
{
printf("%s\n", words[j]);
if (strcmp (words[j], "word we are lookong for") == 0)
{
// found it
}
}

Related

C - Sorting a dynamically sized array of strings

I'm quite new to C and trying to read an input stream of data from a file, appending it to a dynamically sized array, which works well to that point.
After that, I want to sort the array alphabetically. I read the manpages of strcmp and think it's the best way to do this. However, I get hit by a "Segmentation Fault" whenever i'm trying to execute it. What exactly am I doing wrong when allocating the memory?
Here is my code for reference:
int main (int argc, char* argv[]) {
int c = getLineCount();
FILE * wordlist = fopen("test", "r");
// If file doesn't exist, handle error
if ( wordlist == NULL ) {
fputs("Unable to open input file", stderr);
exit(1);
}
int length = 101;
char line[length];
int i = 0;
char **words = malloc(c * sizeof(line));
if ( words == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
while (1) {
char *l = fgets(line, length, wordlist);
if ( (l == NULL) ) {
// Check if EOF is reached
if (feof(wordlist)) {
// fputs("--- EOF ---\n", stdout);
break;
// Check if error occured while reading
} else {
fputs("Error reading file", stderr);
exit(1);
}
} else if (strchr(line, '\n') == NULL) {
// Check if line is too long
// Iterate until newline is found or until EOF
int c;
while((c = fgetc(wordlist)) != '\n' && c != 0);
fputs("--- LINE TOO LONG ---\n", stderr);
continue;
} else if ( line[0] == '\n' ) {
// Check if line is only "\n", if yes, ignore the line
continue;
} else {
words[i] = malloc(sizeof(line) * sizeof(char));
if ( words[i] == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
strcpy(words[i], line);
i++;
}
}
// Close file
fclose(wordlist);
char temp[101];
for (int i = 0; i < (length-1); i++) {
int lowest = i;
for (int j = i+1; j < length; j++) {
if (strcmp(words[j], words[lowest]) < 0) {
lowest = j;
}
}
if (lowest != i) {
strcpy(temp, words[i]);
words[i] = words[lowest];
free(words[lowest]);
words[lowest] = malloc(sizeof(temp) * sizeof(char));
if ( words[lowest] == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
strcpy(words[lowest], temp);
}
}
// Print out array
fputs("--- ARRAY ---\n\n", stdout);
for (int i = 0; i < c; i++) {
fputs(words[i], stdout);
}
exit(0);
}
The upper bounds of the sorting algorithm is length, which is incorrect, as length is the size of the input line buffer.
for (int i = 0; i < (length-1); i++) {
The upper bounds should be i from the outer scope here, as it is incremented when a new line is added to the array:
strcpy(words[i], line);
i++;
This upper bounds
for (int i = 0; i < c; i++) {
should be changed as as well, as the number of valid lines might not match the number of expected lines.
Don't forget to free your memory after you are done with it.
These two lines quickly create a memory leak (original pointer value of words[i] is lost), and then set up a use-after-free bug, since the new value of words[i] is the same pointer value as words[lowest], which is freed.
words[i] = words[lowest];
free(words[lowest]);
There is no need for the extra buffer, the (de)allocations, and the string copying here. Just swap the pointer values like you would if you were sorting an array of integers, for example.
char *tmp = words[i];
words[i] = words[lowest];
words[lowest] = tmp;
Here is a common cursory example, without error handling, using strdup. It should illustrate swapping pointer values, and determining the length of the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 256
int main(void) {
char line[4096];
char **lines = malloc(sizeof *lines * MAX_LINES);
size_t len = 0;
while (len < MAX_LINES && fgets(line, sizeof line, stdin))
lines[len++] = strdup(line);
for (size_t i = 0; i < len - 1; i++) {
size_t lowest = i;
for (size_t j = i + 1; j < len; j++)
if (strcmp(lines[j], lines[lowest]) < 0)
lowest = j;
if (lowest != i) {
char *tmp = lines[i];
lines[i] = lines[lowest];
lines[lowest] = tmp;
}
}
for (size_t i = 0; i < len; i++) {
printf("%s", lines[i]);
free(lines[i]);
}
free(lines);
}
stdin:
one
two
hello
foo
world
^D
stdout:
foo
hello
one
two
world

To mimic sort command of linux, to sort lines of a text file

Sort command of linux must sort the lines of a text file and transfer the output to another file. But my code gives a runtime error. Please rectify the pointer mistakes so that output.
In which line exactly should I make changes? Because there is no output after all.
I'm pasting the whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sortfile(char **arr, int linecount) {
int i, j;
char t[500];
for (i = 1; i < linecount; i++) {
for (j = 1; j < linecount; j++) {
if (strcmp(arr[j - 1], arr[j]) > 0) {
strcpy(t, arr[j - 1]);
strcpy(arr[j - 1], arr[j]);
strcpy(arr[j], t);
}
}
}
}
int main() {
FILE *fileIN, *fileOUT;
fileIN = fopen("test1.txt", "r");
unsigned long int linecount = 0;
int c;
if (fileIN == NULL) {
fclose(fileIN);
return 0;
}
while ((c = fgetc(fileIN)) != EOF) {
if (c == '\n')
linecount++;
}
printf("line count=%d", linecount);
char *arr[linecount];
char singleline[500];
int i = 0;
while (fgets(singleline, 500, fileIN) != NULL) {
arr[i] = (char*)malloc(500);
strcpy(arr[i], singleline);
i++;
}
sortfile(arr, linecount);
for (i = 0; i < linecount; i++) {
printf("%s\n", arr[i]);
}
fileOUT = fopen("out.txt", "w");
if (!fileOUT) {
exit(-1);
}
for (i = 0; i < linecount; i++) {
fprintf(fileOUT, "%s", arr[i]);
}
fclose(fileIN);
fclose(fileOUT);
}
The problem in your code is you do not rewind the input stream after reading it the first time to count the number of newlines. You should add rewind(fileIN); before the next loop.
Note however that there are other problems in this code:
the number of newline characters may be less than the number of successful calls to fgets(): lines longer than 499 bytes will be silently broken in multiple chunks, causing more items to be read by fgets() than newlines. Also the last line might not end with a newline. Just count the number of successful calls to fgets().
You allocate 500 bytes for each line, which is potentially very wasteful. Use strdup() to allocate only the necessary size.
Swapping the lines in the sort routine should be done by swapping the pointers, not copying the contents.
allocating arr with malloc is safer and more portable than defining it as a variable sized array with char *arr[linecount];
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sortfile(char **arr, int linecount) {
for (;;) {
int swapped = 0;
for (int j = 1; j < linecount; j++) {
if (strcmp(arr[j - 1], arr[j]) > 0) {
char *t = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = t;
swapped = 1;
}
}
if (swapped == 0)
break;
}
}
int main() {
FILE *fileIN, *fileOUT;
char singleline[500];
int i, linecount;
fileIN = fopen("test1.txt", "r");
if (fileIN == NULL) {
fprintf(stderr, "cannot open %s\n", "test1.txt");
return 1;
}
linecount = 0;
while (fgets(singleline, 500, fileIN)) {
linecount++;
}
printf("line count=%d\n", linecount);
char **arr = malloc(sizeof(*arr) * linecount);
if (arr == NULL) {
fprintf(stderr, "memory allocation failure\n");
return 1;
}
rewind(fileIN);
for (i = 0; i < linecount && fgets(singleline, 500, fileIN) != NULL; i++) {
arr[i] = strdup(singleline);
if (arr[i] == NULL) {
fprintf(stderr, "memory allocation failure\n");
return 1;
}
}
fclose(fileIN);
if (i != linecount) {
fprintf(stderr, "line count mismatch: i=%d, lilnecount=%d\n",
i, linecount);
linecount = i;
}
sortfile(arr, linecount);
for (i = 0; i < linecount; i++) {
printf("%s", arr[i]);
}
fileOUT = fopen("out.txt", "w");
if (!fileOUT) {
fprintf(stderr, "cannot open %s\n", "out.txt");
return 1;
}
for (i = 0; i < linecount; i++) {
fprintf(fileOUT, "%s", arr[i]);
}
fclose(fileOUT);
for (i = 0; i < linecount; i++) {
free(arr[i]);
}
free(arr);
return 0;
}
To get a different sort order, you would change the comparison function. Instead of strcmp() you could use this:
#include <ctype.h>
int my_strcmp(const char *s1, const char *s2) {
/* compare strings lexicographically but swap lower and uppercase letters */
unsigned char c, d;
while ((c = *s1++) == (d = *s2++)) {
if (c == '\0')
return 0; /* string are equal */
}
/* transpose case of c */
if (islower(c)) {
c = toupper(c);
} else {
c = tolower(c);
}
/* transpose case of d */
if (islower(d)) {
d = toupper(d);
} else {
d = tolower(d);
}
/* on ASCII systems, we should still have c != d */
/* return comparison result */
if (c <= d)
return -1;
} else {
return 1;
}
}

Uninitialised values in dynamic array in C

I've been given a task that requires a dynamic 2D array in C, but we haven't even covered pointers yet, so I'm kind of at a loss here. I have to read some text input and store it in a 2D array, without limiting its size.
Unfortunately, Valgrind keeps throwing me an error saying that there's an uninitialised value, when the puts() function executes and sometimes it prints out some random signs. I understand that I must have omitted some indexes, but I just can't find where the issue stems from. Additionally, all advices regarding the quality of my code are very much appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#define MULT 3
#define DIV 2
char **read(int *row, int *col) {
char **input = NULL;
int row_size = 0;
int col_size = 0;
int i = 0;
int c;
while ((c = getchar()) != EOF) {
if (c != '\n') { // skip empty lines
assert(i < INT_MAX);
if (i == row_size) { // if not enough row memory, allocate more
row_size = 1 + row_size * MULT / DIV;
input = realloc(input, row_size * sizeof *input);
assert(input != NULL);
}
char *line = NULL;
int j = 0;
// I need all the rows to be of the same size (see last loop)
line = malloc(col_size * sizeof *line);
// do while, so as to not skip the first character
do {
assert(j < INT_MAX-1);
if (j == col_size) {
col_size = 1 + col_size * MULT / DIV;
line = realloc(line, col_size * sizeof *line);
assert(line != NULL);
}
line[j++] = c;
} while(((c = getchar()) != '\n') && (c != EOF));
// zero-terminate the string
if (j == col_size) {
++col_size;
line = realloc(line, col_size * sizeof *line);
line[j] = '\0';
}
input[i++] = line;
}
}
// Here I give all the lines the same length
for (int j = 0; j < i; ++j)
input[j] = realloc(input[j], col_size * sizeof *(input+j));
*row = i;
*col = col_size;
return input;
}
int main(void) {
int row_size, col_size, i, j;
char **board = read(&row_size, &col_size);
// Initialize the remaining elements of each array
for (i = 0; i < row_size; ++i) {
j = 0;
while (board[i][j] != '\0')
++j;
while (j < col_size-1)
board[i][++j] = ' ';
}
for (i = 0; i < row_size; ++i) {
puts(board[i]);
}
for (i = 0; i < row_size; ++i)
free(board[i]);
free(board);
return 0;
}

C: Why will I get an error on free()

I wrote the following function which will break in the lines marked with // Breakpoint:
char *parseNextWord(char *str)
{
static char *lastStr = "";
static int lastPosition = 0;
if (strcmp(lastStr, str) != 0)
{
lastStr = str;
lastPosition = 0;
}
if (lastPosition > 0 && str[lastPosition - 1] == 0)
{
return 0;
}
char *word = "";
int wLength = 0;
while (str[lastPosition] != ' ' && str[lastPosition] != '\n' && str[lastPosition] != '\0')
{
char *tmp = (char*)malloc(++wLength * sizeof(char));
for (int i = 0; i < sizeof(word); i++)
{
tmp[i] = word[i];
}
tmp[sizeof(*tmp) - 1] = str[lastPosition];
free(word); // Breakpoint
word = (char*)malloc(sizeof(*tmp));
for (int i = 0; i < sizeof(tmp); i++)
{
word[i] = tmp[i];
}
free(tmp); // Breakpoint
lastPosition++;
}
while (str[lastPosition - 1] != '\0' && (str[lastPosition] == ' ' || str[lastPosition] == '\n' || str[lastPosition] == '\0'))
{
lastPosition++;
}
return word;
}
The function can be called like this:
char* string = "Name1 Name2\nName3 Name4\nName1";
int totalCount = 0;
char *nextWord = parseNextWord(string);
while (nextWord != 0)
{
for (int c = 1; c < argc; c++)
{
if (strcmp((const char*)argv[c], nextWord) == 0)
{
totalCount++;
}
}
nextWord = parseNextWord(string);
}
Why is my code breaking on free? How can I improve it?
The relevant code I see is:
char* word = "";
free(word);
You did not allocate the empty string (""), so you cannot free it.
You can only free what you malloc
If you didn't allocate it, don't try to free it.
P.S. Here is my best list of functions which allocate memory that can be freed:
malloc
realloc
calloc
strdup
asprintf
vasprintf
(notably: _not_ alloca)
Maybe there are others as well?
because you didn't allocate word the first time you entered the loop.
you just make it point to "" which is not allocated dynamically.
my suggestion to make it work is to add integer variable before the while with initial value 0 :
if (flag != 0) {
free(word);
} else {
word = 1;
}

Reading and analyzing rooms from text file

My program crashes and I can't find where. I tried debugging with printf on almost every line, but I just can't find what's wrong. I THINK that it may be at the readLine function, but I'm just completely lost.
The input file that I'm using is
*HallStudyCellarKitchen*StudyHallGarden*CellarHall*KitchenHallGarden*GardenStudyKitchen
Which means that every '*' separates a new room and then it shows where doors in that room lead to.
Code of my program
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
#define BMAX 100
struct room * rooms[MAX];
int rp; // room count
// struct room - name, array of up to 4 doors, number of doors
struct room {char * name; struct door * doors[4]; int dp;};
// struct door - name for the room it connects to, & a pointer to that room
struct door {char * name; struct room * room;};
struct door * newDoor(char * name){
struct door * d; // pointer d to the address of door
d = (struct door *) malloc(sizeof(struct door));
d->name = name; // name of new door is name
d->room = NULL; // NULL room pointer
return d;
};
struct room * newRoom(char * name){
struct room * r; // pointer r to the address of room
printf("New room is %s\n",name);
r = (struct room *) malloc(sizeof(struct room));
r->name = name; // name of new room is name
r->dp = 0; // no doors
return r;
};
showRoom(struct room * r){
int i;
printf("room name: %s\n", r->name);
for (i = 0; i < (r->dp); r++){
printf("%d %s\n", i,r->doors[i]->name);
}
}
showRooms(){
int i;
for (i = 0; i < rp; i++){
showRoom(rooms[i]);
}
}
char * readLine(FILE * fin){
char buffer[BMAX];
int i,j;
char ch;
char * l;
i = 0;
ch = getc(fin);
if (ch == EOF)
return NULL;
while (ch!='\n' && i < (BMAX - 1)){
buffer[i] = ch;
i++;
ch = getc(fin);
}
if (ch != '\n')
while (ch != '\n')
ch = getc(fin);
buffer[i] = '\0';
l = malloc((i+1) * sizeof(char));
for (j = 0; j <= i; j++)
l[j] = buffer[j];
l[j] = '\0';
return l;
}
readRooms(FILE * fin)
{ char * l;
rp = 0;
// printf("3"); fflush(stdout);
while((l = readLine(fin)) != NULL)
{
if(rp > MAX)
{
printf("it's too many rooms\n");
exit(0);
}
//printf("%s",l);
rooms[rp] = newRoom(l);
//l = readLine(fin);
if (strncmp(l,"*")==0){
//printf("2"); fflush(stdout);
rp++;
}
while(strncmp(l,"*")!=0)
{
//printf("1"); fflush(stdout);
if((rooms[rp] -> dp) > 4)
{ printf("it's too many doors\n");
exit(0);
}
rooms[rp] -> doors[rooms[rp] -> dp] = newDoor(l);
rooms[rp] -> dp++;
l = readLine(fin);
}
//rooms[rp] -> dp = 0;
//rp++;
//l = readLine(fin);
}
}
connect()
{ int i,j,k;
for(i = 0; i < rp; i++)
for(j = 0; j < rooms[i]->dp; j++)
{ for(k = 0; k < rp; k++)
if(strcmp(rooms[k]->name,rooms[i]->doors[j]->name) == 0)
{ rooms[i]->doors[j]->room = rooms[k];
break;
}
if(k == rp)
{ printf("can't find %s\n",rooms[i]->doors[j]->name);
exit(0);
}
}
}
int main(int argc,char ** argv){
FILE * fin;
struct room * r; // current room
// struct door * d;
int d;
if((fin=fopen(argv[1],"r"))==NULL)
{ printf("cannot open %s\n",argv[1]);
exit(EXIT_FAILURE);
}
printf("11"); fflush(stdout);
readRooms(fin);
printf("22");
fclose(fin);
showRooms();
connect();
r = rooms[0];
while(1)
{ showRoom(r);
printf("enter door number> ");
scanf("%d",&d);
if(d >= (r->dp))
printf("bad door number\n");
else
r = r->doors[d]->room;
}
return EXIT_SUCCESS;
}
What might be causing the crash, and how can I resolve it?
The readLine function does look a bit error prone:
char * readLine(FILE * fin){
char buffer[BMAX];
int i,j;
char ch;
char * l;
i = 0;
ch = getc(fin);
if (ch == EOF)
return NULL;
while (ch!='\n' && i < (BMAX - 1)){
buffer[i] = ch;
i++;
ch = getc(fin);
}
// The test on the next line is not necessary: it will be caught
// by the first run of the following while loop.
if (ch != '\n')
while (ch != '\n')
ch = getc(fin);
buffer[i] = '\0';
// Allocate a region of memory of (probably) i+1 bytes
l = malloc((i+1) * sizeof(char));
// j will range from zero to i, terminating when j = i+1
for (j = 0; j <= i; j++)
l[j] = buffer[j];
// j now equals i+1 and l[j] is one beyond the size of the memory allocated at l.
l[j] = '\0';
return l;
}
Fix this by changing the condition on the loop
// j will range from zero to i-1, terminating when j = i
for (j = 0; j < i; j++)
l[j] = buffer[j];
// j now equals i and l[j] is the last element of the memory allocated at l.
l[j] = '\0';
Notes:
1) You should always check the return value from malloc.
2) The actual size of memory allocated by malloc may be more than that requested, depending on the heap implementation, the processor architecture and the actual library function used.
Also, you should be nice and call free on every pointer that you have assigned using malloc. The memory will be cleaned up eventually when the process terminates (if it's running in a fairly common OS), but it's good practice to do housekeeping, especially on those temporary buffers returned by readLine.
You may also want to take a look at the if(rp > MAX) line in readRooms and see if could cause an over run for the 11th room.
Incorrect usage of int strncmp(const char *s1, const char *s2, size_t n); in 2 places. Suggest replacing with strcmp().
// if (strncmp(l,"*")==0)
if (strcmp(l,"*")==0)
If your compiler did not warning about this, either enable more warnings or get a new compiler.
Suspect off by 1
// if (rp > MAX)
if (rp >= MAX)
// if((rooms[rp] -> dp) > 4)
if ((rooms[rp] -> dp) >= 4)
Minor fixes to readLine() follow
char * readLine(FILE * fin){
char buffer[BMAX];
int i,j;
// char ch;
int ch;
char * l;
i = 0;
ch = getc(fin);
if (ch == EOF)
return NULL;
// while (ch!='\n' && i < (BMAX - 1)){
while (ch!='\n' && ch!= EOF && i < (BMAX - 1)){
buffer[i] = ch;
i++;
ch = getc(fin);
}
if (ch != '\n')
// while (ch != '\n')
while (ch != '\n' && ch!= EOF)
ch = getc(fin);
buffer[i] = '\0';
// l = malloc((i+1) * sizeof(char));
l = malloc(i+1); // sizeof(char) is always 1
if (l == NULL) Handle_OOM();
for (j = 0; j <= i; j++)
l[j] = buffer[j];
l[j] = '\0';
return l;
}
What might be causing the crash, and how can I resolve it?
One possible (and the probable) cause of the crash is this loop in readRooms():
while(strncmp(l,"*")!=0)
{
//printf("1"); fflush(stdout);
if((rooms[rp] -> dp) > 4)
{ printf("it's too many doors\n");
exit(0);
}
rooms[rp] -> doors[rooms[rp] -> dp] = newDoor(l);
rooms[rp] -> dp++;
l = readLine(fin);
}
The l = readLine(fin) at the end of the loop sets l to NULL when EOF is reached, and this null pointer is wrongly passed to strncmp() (also which is, as chux noted, missing the third argument).
Before you can resolve that, you must make up your mind about the input file format, that is to say whether the rooms go on one and the same line, as in your question - then you can't read a single room with readLine() in its current form - or the rooms go on separate lines.

Resources