mallocAllocate memory for an int?
int *p = malloc(sizeof(int));
*p = 42;
printf("%d\n", *p);
Allocate memory for ints?
int *p = malloc(sizeof(int) * n);
for (int i = 0; i < n; ++i)
scanf("%d", p + i); // What does `p + i` mean?
mallocmallocAllocate memory for a "2-d" array with
Another way: Allocate a "1-d" array of
int *p = malloc(sizeof(int) * n * m);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
scanf("%d", &a[i * m + j]); // a[i * m + j] is the (i, j)-th entry
freefree?free(NULL) do?free?free(ptr), what is the value of ptr?free an address twice?freeWhat pointer should be passed to free?
malloc, calloc, aligned_alloc and realloc).What does free(NULL) do?
What if we forget to free?
freeAfter a call to free(ptr), what is the value of ptr?
ptr becomes a dangling pointer, which cannot be dereferenced.What will happen if we free an address twice?
malloc and freeWhich of the following pieces of code deallocate(s) the memory correctly?
int *p = malloc(sizeof(int) * 100);
free(p);for (int i = 0; i < 100; ++i) free(p + i);free(p + 50); free(p);for (int i = 0; i < 10; ++i) free(p + i * 10);malloc and freeWhich of the following pieces of code deallocate(s) the memory correctly?
int *p = malloc(sizeof(int) * 100);
free(p); Yesfor (int i = 0; i < 100; ++i) free(p + i); Nofree(p + 50); free(p); Nofor (int i = 0; i < 10; ++i) free(p + i * 10); NoYou cannot deallocate only a part of the memory block!
'\0' at the end.strlen(s)scanf / printf with "%s"fgets, putsHow does a function accept and handle a string?
char *, indicating the start of the string.'\0'.printf(NULL)?How does a function accept and handle a string?
char *, indicating the start of the string.'\0'.printf(NULL)?
printf expects a string for the first argument, which should contain at least a character '\0'.* Differentiate between the null character '\0', the empty string "" and the null pointer NULL.
The following command executes gcc.exe, and tells it the file to be compiled and the name of the output:
gcc hello.c -o hello
How are the arguments hello.c, -o and hello passed to gcc.exe?
mainint main(int argc, char **argv) { /* body */ }
Run this program with some arguments: .\program one two three
int main(int argc, char **argv) {
for (int i = 0; i < argc; ++i)
puts(argv[i]);
}
Output:
.\program
one
two
three
mainint main(int argc, char **argv) { /* body */ }
where
argc is a non-negative value representing the number of arguments passed to the program from the environment in which the program is run.argv is a pointer to the first element of an array of argc + 1 pointers, of which
If argv[0] is not null (or equivalently, if argc > 0), it points to a string representing the program name.
int main(int argc, char **argv) { /* body */ }
argv is an array of pointers that point to the strings representing the arguments:
fgets(str, count, stdin) reads a string, but at most count - 1 characters.
scanf("%s", str) reads a string, but not caring about whether the input content is too long to fit into the memory that str points to.
For example, the following code is likely to crash if the input is responsibility:
char word[6];
scanf("%s", word);
scanf does nothing to prevent the disaster.
word is!Suppose we want to read a sequence of non-whitespace characters, the length of which is unknown.
malloc / free to allocate and deallocate memory dynamically.char *read_string(void) {
char c = getchar();
while (isspace(c))
c = getchar();
}
char *read_string(void) {
char c = getchar();
while (isspace(c))
c = getchar();
char *buffer = malloc(INITIAL_SIZE);
int capacity = INITIAL_SIZE;
int cur_pos = 0; // The index at which we store the input character.
}
char *read_string(void) {
// ignore leading whitespaces
char *buffer = malloc(INITIAL_SIZE);
int capacity = INITIAL_SIZE;
int cur_pos = 0; // The index at which we store the input character.
while (!isspace(c)) {
if (cur_pos == capacity - 1) { // `-1` is for '\0'.
}
buffer[cur_pos++] = c;
c = getchar();
}
}
char *read_string(void) {
// ...
while (!isspace(c)) {
if (cur_pos == capacity - 1) { // `-1` is for '\0'.
char *new_buffer = malloc(capacity * 2);
memcpy(new_buffer, buffer, cur_pos); // copy everything we have stored
// to the new buffer
capacity *= 2;
buffer = new_buffer;
}
buffer[cur_pos++] = c;
c = getchar();
}
}
* Are we done?
free!char *read_string(void) {
// ...
while (!isspace(c)) {
if (cur_pos == capacity - 1) { // `-1` is for '\0'.
char *new_buffer = malloc(capacity * 2);
memcpy(new_buffer, buffer, cur_pos); // copy everything we have stored
// to the new buffer
free(buffer); // !!!!!!!!!!!
capacity *= 2;
buffer = new_buffer;
}
buffer[cur_pos++] = c;
c = getchar();
}
}
char *read_string(void) {
// ...
while (!isspace(c)) {
if (cur_pos == capacity - 1) { // `-1` is for '\0'.
// ...
}
buffer[cur_pos++] = c;
c = getchar();
}
// Now, `c` is a whitespace. This is not part of the contents we need.
ungetc(c, stdin); // Put that whitespace back to the input.
return buffer;
}
* Are we done?
char *read_string(void) {
// ...
while (!isspace(c)) {
if (cur_pos == capacity - 1) { // `-1` is for '\0'.
// ...
}
buffer[cur_pos++] = c;
c = getchar();
}
// Now, `c` is a whitespace. This is not part of the contents we need.
ungetc(c, stdin); // Put that whitespace back to the input.
buffer[cur_pos] = '\0'; // Remember this!!!
return buffer;
}
int main(void) {
char *content = read_string();
puts(content);
free(content);
}
Remember to free it after use!