{"record":{"id":"09bf29d4f316ac6d","repo":"Yalantis/uCrop","slug":"save-ascii-specified-filename-is-null","errorCode":null,"errorMessage":"save_ascii(): Specified filename is (null).","messagePattern":"save_ascii\\(\\): Specified filename is \\(null\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":61385,"sourceCode":"      return save_other(fn);\n    }\n\n    //! Save image as an ascii file.\n    /**\n      \\param filename Filename, as a C-string.\n    **/\n    const CImg<T>& save_ascii(const char *const filename) const {\n      return _save_ascii(0,filename);\n    }\n\n    //! Save image as an Ascii file \\overloading.\n    const CImg<T>& save_ascii(std::FILE *const file) const {\n      return _save_ascii(file,0);\n    }\n\n    const CImg<T>& _save_ascii(std::FILE *const file, const char *const filename) const {\n      if (!file && !filename)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_ascii(): Specified filename is (null).\",\n                                    cimg_instance);\n      std::FILE *const nfile = file?file:cimg::fopen(filename,\"w\");\n      std::fprintf(nfile,\"%u %u %u %u\\n\",_width,_height,_depth,_spectrum);\n      const T* ptrs = _data;\n      cimg_forYZC(*this,y,z,c) {\n        cimg_forX(*this,x) std::fprintf(nfile,\"%.17g \",(double)*(ptrs++));\n        std::fputc('\\n',nfile);\n      }\n      if (!file) cimg::fclose(nfile);\n      return *this;\n    }\n\n    //! Save image as a .cpp source file.\n    /**\n      \\param filename Filename, as a C-string.\n    **/\n    const CImg<T>& save_cpp(const char *const filename) const {","sourceCodeStart":61367,"sourceCodeEnd":61403,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L61367-L61403","documentation":"save_ascii() can write to either an open std::FILE* or a filename; _save_ascii() throws CImgArgumentException when BOTH are null because there is no output destination. It is the shared implementation behind save_ascii(std::FILE*) and save_ascii(filename).","triggerScenarios":"Calling img.save_ascii((std::FILE*)NULL) or img.save_ascii((const char*)NULL); also a FILE* that failed fopen (returned NULL) forwarded into the FILE*-overload with no filename.","commonSituations":"fopen failure earlier in code whose NULL result was passed on, refactoring changed call from filename overload to FILE* overload passing 0, optional-output logic that skips creating a file but still calls save.","solutions":["Ensure fopen succeeded (non-NULL FILE*) before calling the FILE* overload.","Call the filename overload (save_ascii(\"out.txt\")) instead of the FILE* overload when no file is open.","Check both file and filename are not null at the call site.","Handle fopen errors (errno) before attempting to save."],"exampleFix":"// before\nFILE* f = fopen(\"out.txt\", \"w\");\nimg.save_ascii(f); // f may be NULL\n// after\nFILE* f = fopen(\"out.txt\", \"w\");\nif (f) { img.save_ascii(f); fclose(f); }\nelse img.save_ascii(\"out.txt\"); // fallback by filename","handlingStrategy":"type-guard","validationCode":"if (!file && (!filename || !*filename)) { /* abort or fallback to default filename */ }","typeGuard":"bool hasDestination(std::FILE* f, const char* n){ return f!=nullptr || (n!=nullptr && *n!='\\0'); }","tryCatchPattern":"try { img.save_ascii(f); } catch (CImgArgumentException& e) { /* reopen by filename fallback */ img.save_ascii(\"out.txt\"); }","preventionTips":["Check fopen result for NULL before the FILE* overload","Prefer filename overloads unless you manage the stream yourself","Close/NULL out FILE* handles deterministically to avoid stale null pointers"],"tags":["cimg","save","null-pointer","file-io"],"backgroundTag":"null-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}