求助:使用malloc的C程序program.exe出现运行终止问题
Hey there, let's walk through exactly why your program is throwing that malloc-related crash and get it working properly. I see a few key issues here:
1. Insufficient Memory Allocation + Unsafe gets() Function
You only allocated 1 byte of memory with malloc(sizeof(char)), but gets() reads the entire user-input string—no matter how long it is—right into that tiny buffer. This causes a buffer overflow, which corrupts the heap memory structure that malloc/free rely on. That's directly why you're seeing the "malloc has stopped working" error.
On top of that, gets() is a completely unsafe function (it's been deprecated since C11 for this exact reason) because it never checks the size of the buffer it's writing to.
2. Freeing the Wrong Memory Address
In your while loop, you're doing *s++, which moves the pointer s forward through the string. By the time you call free(s), s is no longer pointing to the original address returned by malloc—you're trying to free a random memory location, which is an illegal operation and will crash your program.
Fixed Code with Explanations
Here's a corrected version of your code, with comments explaining each change:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> // Use standard int main() instead of void main() (complies with C standards) int main() { // Allocate a sufficiently large buffer (1024 bytes) to hold user input char *s = (char*)malloc(1024 * sizeof(char)); // Always check if malloc succeeded (it can fail if system is out of memory) if (s == NULL) { perror("Failed to allocate memory"); return 1; } printf("Enter a string:\n"); // Replace unsafe gets() with fgets()—it limits the number of bytes read fgets(s, 1024, stdin); // Remove the trailing newline character that fgets might capture size_t str_length = strlen(s); if (str_length > 0 && s[str_length - 1] == '\n') { s[str_length - 1] = '\0'; } // Save the original malloc address so we can free it later char *original_ptr = s; while (*s) { // Use character constants ('A', 'Z') instead of raw ASCII codes for readability if (*s >= 'A' && *s <= 'Z') printf("%c", *s + 32); else if (*s >= 'a' && *s <= 'z') printf("%c", *s - 32); else printf("%c", *s); s++; // No need for *s++ here—we just need to move the pointer, not dereference it } printf("\n"); // Add a newline for clean output // Free the original memory address, not the modified pointer free(original_ptr); return 0; }
Key Changes Made:
- Standardized
main(): Switched fromvoid main()toint main()and added a return value—this is required by the C standard. - Safe Memory Allocation: Allocated a 1024-byte buffer (adjust this if you need to handle longer strings) and added a check for
mallocfailure. - Replaced
gets(): Usedfgets()to safely read input without buffer overflow risks. - Preserved Original Pointer: Saved the initial
mallocaddress to ensure we free the correct memory later. - Improved Readability: Used character constants instead of raw ASCII values, making the code easier to understand.
- Cleaner Output: Added a final newline to make the transformed string look neater.
内容的提问来源于stack exchange,提问作者Hosein Shendabadi

