strlenfor (int i = 0; i < strlen(s); ++i)
// ...
Why does the compiler issue a warning for i < strlen(s)?
strlen is size_t, which is an unsigned integer type.int and size_t, the int value is implicitly converted to size_t.
i is negative (e.g., -1), the comparison -1 < strlen(s) is almost certainly evaluated as false.* Avoid mixing signed and unsigned integers.
strcpySignature: (Defined in header <string.h>)
char *strcpy(char* dest, const char* src);
Behavior:
strcpy function copies the null-terminated byte string pointed to by src, including the null terminator \0, to the character array whose first element is pointed to by dest.dest array is not large enough to hold the contents of src.dest is not a pointer to a character array or src is not a pointer to a null-terminated byte string.strcpy Functionchar *strcpy(char* dest, const char* src);
malloc, callocreallocfreemalloc, callocvoid* malloc(size_t size);
void* calloc(size_t num, size_t each_size);
malloc: Allocates size bytes of uninitialized memory, meaning the values of the allocated elements are indeterminate.
calloc: Allocates memory for an array of num objects, each of size each_size, and initializes all bytes to zero.
num * size.0.0 or pointers are set to the null pointer value.mallocAccording to the C standard, the memory allocated by malloc contains indeterminate values, but in practice, these values often appear as zero. Is this just a coincidence?
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
int *arr = malloc(n * sizeof(int));
printf("Array values:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
For more details, you can check out this answer on StackOverflow.
realloc: reallocates a specified area of memoryvoid* realloc(void* ptr, size_t new_size);
The parameter ptr may be either NULL or a pointer that was previously allocated by malloc, calloc, or realloc, and has not yet been freed with a call to free or realloc.
ptr is NULL, the behavior is equivalent to that of malloc(new_size).ptr is not NULL, the allocation is performed by:
ptr, ornew_size bytes, copying the memory area equal to the lesser of the new or old sizes, and freeing the old block.If sufficient memory is not available, the old memory block is not freed, and a null pointer is returned.
malloc, calloc, and reallocTo prevent memory leaks, any pointer returned by these functions must be deallocated using free (or realloc). It is important to note that the original pointer ptr becomes invalidated after reallocation, and any subsequent access to it results in undefined behavior, even if the reallocation occurs in-place.
The behavior of malloc(0), calloc(0, N), calloc(N, 0), and realloc(ptr, 0) is implementation-defined.
free: void free(void* ptr)OK:
ptr != NULL.Undefined Behavior:
free.malloc, calloc, realloc, or C11's aligned_alloc.
Reminder:
Forgetting to call free can lead to memory leaks, which may prevent you from passing tests on an Online Judge (OJ) platform.
memcpyungetc// Method 1: create an real 2D array
int **p = malloc(sizeof(int *) * n);
for (int i = 0; i != n; ++i)
p[i] = malloc(sizeof(int) * m);
for (int i = 0; i != n; ++i)
for (int j = 0; j != m; ++j)
p[i][j] = /* ... */
for (int i = 0; i != n; ++i)
free(p[i]);
free(p);
// Method 2: create an 1D array
int *p = malloc(sizeof(int) * n * m);
for (int i = 0; i != n; ++i)
for (int j = 0; j != m; ++j)
p[i * m + j] = /* ... */
// ...
free(p);
Suppose we need to read a sequence of non-whitespace characters of unknown length. In such cases, we can dynamically allocate memory using malloc and resize it as needed using realloc. The steps include:
// Snippet 1
char *read_string(void) {
// ignore leading whitespaces
char c = getchar();
while (isspace(c))
c = getchar();
char *buffer = malloc(INITIAL_SIZE);
int capacity = INITIAL_SIZE;
int cur_pos = 0;
// Snippet 2
while (!isspace(c)) {
if (cur_pos == capacity - 1) {
char *new_buffer = malloc(capacity * 2);
// copy everything what we have stored
// to the new buffer
memcpy(new_buffer, buffer, cur_pos);
// Don't forget to free.
free(buffer);
capacity *= 2;
buffer = new_buffer;
}
buffer[cur_pos++] = c;
c = getchar();
}
// Snippet 3
// 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;
}
memcpyDefined in header <string.h>:
void* memcpy(void* dest, const void* src, size_t count);
count characters from the memory location pointed to by src to the memory location pointed to by dest. The function returns dest.dest does not have enough space to hold count characters.src and dest memory regions overlap.src or dest is an invalid or null pointer.memcpy is faster than strcpy, which stops when it encounters \0, while memcpy copies the exact number of bytes specified without scaning the data.ungetcint ungetc(int ch, FILE* stream); // defined in header <stdio.h>
ungetc pushes the character ch back into the input buffer for the stream stream. The next read operation from this stream will retrieve this pushed-back character.
ungetc is called more than once before a read or repositioning occurs, the behavior is implementation-defined and may fail.ungetc calls are made, the pushed-back characters will be read in reverse order.